[Spring] Controller 분리

jsieon97·2023년 3월 2일

[Spring] BackEnd

목록 보기
6/11

Controller 분리

@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request) {
  String readSql = "SELECT * FROM user WHERE id = ?";
  boolean isUserNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getI
  d()).isEmpty();
  if (isUserNotExist) {
  	throw new IllegalArgumentException();
  }
  String updateSql = "UPDATE user SET name = ? WHERE id = ?";
  jdbcTemplate.update(updateSql, request.getName(), request.getId());
}

위 코드는 UserController 코드의 일부입니다.

컨트롤러 하나에 많은 역할이 부여되어있는 것을 볼 수 있습니다.
총 3가지부분
1. API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다.
2. 현재 유저가 있는지, 없는지 등을 확인하고 예외 처리를 해준다.
3. SQL을 사용해 실제 DB와의 통신을 담당한다.
으로 나뉘어져 있고 이를 3가지로 분리하여 유지보수를 편리하도록 Clean Code를 작성해 보겠습니다.

  1. Controller
    API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다.
package com.group.libraryapp.controller.user;

import com.group.libraryapp.dto.user.request.UserCreateRequest;
import com.group.libraryapp.dto.user.request.UserUpdateRequest;
import com.group.libraryapp.dto.user.response.UserResponse;
import com.group.libraryapp.service.user.UserService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/user")
    public void saveUser(@RequestBody UserCreateRequest request) {
        if (userRepository.isUserNotExist(name)) {
            throw new IllegalArgumentException();
        }

        userRepository.saveUser(request.getName(), request.getAge());
    }
}
  1. Service
    현재 유저가 있는지, 없는지 등을 확인하고 예외처리합니다.
package com.group.libraryapp.service.user;

import com.group.libraryapp.dto.user.request.UserCreateRequest;
import com.group.libraryapp.dto.user.request.UserUpdateRequest;
import com.group.libraryapp.dto.user.response.UserResponse;
import com.group.libraryapp.repository.user.UserRepository;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void saveUser(UserCreateRequest request) {
        userRepository.saveUser(request.getName(), request.getAge());
    }
}
  1. Repository
    SQL을 사용해 실제 DB와의 통신을 담당한다.
package com.group.libraryapp.repository.user;

import com.group.libraryapp.dto.user.response.UserResponse;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.persistence.criteria.CriteriaBuilder;
import java.util.List;


@Repository
public class UserRepository {

    private final JdbcTemplate jdbcTemplate;

    public UserRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    
    public boolean isUserNotExist(long id) {
        String readSql = "SELECT * FROM user WHERE id = ?";
        return jdbcTemplate.query(readSql, (rs, rowNum) -> 0, id).isEmpty();
    }

    public void saveUser(String name, Integer age) {
        String sql = "INSERT INTO  user (name, age) VALUES(?, ?)";
        jdbcTemplate.update(sql, name, age);
    }

}

이렇게 분리한 후 스프링 컨테이너와 빈을 사용해 의존성을 주입하고 사용할 수 있습니다. @Service, @Repository 어노테이션을 통해 간단하게 스프링 컨테이너, 빈을 적용할 수 있습니다. 스프링 컨테이너와 빈은 다음글에 다뤄보겠습니다.

profile
개발자로써 성장하는 방법

0개의 댓글