🍃 Spring Boot로 개발한 Restful API 작동 프로세스
Web/Java (Spring+JSP)

🍃 Spring Boot로 개발한 Restful API 작동 프로세스

MVC 패턴이란?

  • Controller는 클라이언트로부터 요청을 받음. (처리 과정을 담당)
  • Model은 최종 페이지에 쓰일 데이터를 뷰에 전달한다. (데이터를 담당)
  • View는 최종 페이지를 만들어준다.
  • 이렇게 각자의 역할을 나누는 기법을 MVC 패턴이라고 한다.

 

스프링 부트의 로직

  1. Controller : 웹 브라우저의 요청 전담하여 처리, Service 호출 →
  2. Provider/ Service: 비즈니스 로직(아이디 중복검사,비밀번호 재검사, validation...)을 수행하며, 데이터베이스에 접근하는 DAO를 이용해 결과값을 받아옴.
    1. Provider : Read와 관련된 곳으로, DB에서 select해서 얻어온 값을 가공해서 결과로 추출한다.
    2. Service : Create, Update, Delete와 관련된 곳으로, CUD에서도 Read관련 로직이 필요한 경우가 있는데, 이때는 Provider의 함수를 사용한다.
  3. DAO : 데이터베이스에 접속하여 비즈니스 로직 실행에 필요한 쿼리 호출 ->
  4. DB: 알맞은 쿼리 실행해 반환.

 

실제 작동 프로세스

  • Controller내에서 관련된 Provider/Service의 함수 호출
  • Provider 내에서 DAO 호출하여 데이터베이스 접근
  • DAO내의 함수를 통해 DTO를 받아와서 비즈니스 로직 수행함.
  • 이렇게 가공된 데이터 처리 결과를 가지고 Controller가 필요한 로직 수행 후에 브라우저에게 결과를 응답한다.

 

 

코드 예시

1) Controller

package com.example.demo.src.user;

//클래스 관련 정보 생략 

@RestController
@RequestMapping("/app/users")
public class UserController {
    final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private final UserProvider userProvider;
    @Autowired
    private final UserService userService;
    @Autowired
    private final JwtService jwtService;


    public UserController(UserProvider userProvider, UserService userService, JwtService jwtService){
        this.userProvider = userProvider;
        this.userService = userService;
        this.jwtService = jwtService;
    }

    /**
     * 회원 조회 API
     * [GET] /users
     * 회원 번호 및 이메일 검색 조회 API
     * [GET] /users? Email=
     * @return BaseResponse<List<GetUserRes>>
     */
    //Query String
    @ResponseBody
    @GetMapping("") // (GET) 127.0.0.1:9000/app/users
    public BaseResponse<List<GetUserRes>> getUsers(@RequestParam(required = false) String Email) {
        try{
            if(Email == null){
                List<GetUserRes> getUsersRes = userProvider.getUsers();
                return new BaseResponse<>(getUsersRes);
            }
            // Get Users
            List<GetUserRes> getUsersRes = userProvider.getUsersByEmail(Email);
            return new BaseResponse<>(getUsersRes);
        } catch(BaseException exception){
            return new BaseResponse<>((exception.getStatus()));
        }
    }
    }

@RestController

  • Spring MVC 컨트롤러에 @ResponseBody가 추가된 것으로, RestController의 주용도는 JSON 형태로 객체 데이터를 반환하는 것이다. 데이터를 응답으로 제공하는 RESTFUL API를 개발할 때 주로 사용한다.

  1. Client는 URI 형태로 웹 서비스에 요청을 보낸다.
  2. Mapping되는 Handler와 그 Type을 찾는 DispatcherServlet이 요청을 인터셉트한다.
    1. DispatcherServlet은 Spring MVC application의 web.sml 파일에 등록됨.
    2. 모든 HTTP 요청을 수신하고 이를 컨트롤러 클래스에 위임한다.
    3. 스프링 부트는 이를 자동으로 등록하고 구성하여 수동으로 등록할 필요가 없다.
  3. RestController는 해당 요청을 처리하고 데이터를 반환한다.

@RequestMapping

우리가 특정 URI로 요청을 보내면 Controller에서 어떤 방식으로 처리할지 정의한다. 이때 들어온 요청을 특정 메소드와 매핑하기 위해 사용하는것이 @RequestMapping이다.

  • value : 요청받은 url 설정
  • method : HTTP Method 정의

@ResponseBody

클라이언트와 서버의 비동기 통신을 위해 사용하는 어노테이션으로, 자바 객체를 HTTP 요청의 바디 내용으로 매핑하여 클라이언트로 전송한다. 즉, 클라이언트로 응답 데이터를 전송할때 사용되며, @RestController 어노테이션을 사용하면 자동으로 해당 Body가 붙게 된다.

 

@GetMapping, @PostMapping, @PatchMapping....

해당 어노테이션은 HTTP Method에 맞게 추가하면 된다.

 

2) Service/Provider

@Service
public class UserProvider {

    private final UserDao userDao;
    private final JwtService jwtService;


    final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    public UserProvider(UserDao userDao, JwtService jwtService) {
        this.userDao = userDao;
        this.jwtService = jwtService;
    }

    public List<GetUserRes> getUsers() throws BaseException{
        try{
            List<GetUserRes> getUserRes = userDao.getUsers();
            return getUserRes;
        }
        catch (Exception exception) {
            throw new BaseException(DATABASE_ERROR);
        }
    }
   }

@Service/@Provider 어노테이션이 붙으며, 비즈니스 로직  (validation, 암호화...)을 수행하는 걸 확인할 수 있다.

 

@Service 

- 해당 클래스를 루트 컨테이너에 빈(Bean) 객체로 생성해주는 어노테이션이다.

 

 

3) DAO

@Repository
public class UserDao {

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource){
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public List<GetUserRes> getUsers(){
        String getUsersQuery = "select * from UserInfo";
        return this.jdbcTemplate.query(getUsersQuery,
                (rs,rowNum) -> new GetUserRes(
                        rs.getInt("userIdx"),
                        rs.getString("userName"),
                        rs.getString("ID"),
                        rs.getString("Email"),
                        rs.getString("password"))
                );
    }
  }

-> 직접 데이터베이스에 쿼리를 통해 접근하며, 데이터의 집합체인 DTO를 만들어 반환하는 걸 확인할 수 있다. 

  • @Repository : DB나 파일같은 외부 I/O 작업을 처리할때 사용하는 어노테이션이다. Service와 같이 루트 컨테이너에 빈을 생성하고, DAO 객체를 생성하려면 new가 아닌 해당 컨테이너를 통해서 받아와야 한다. 
    • Bean/Container/DI 관련 포스팅은 이전 포스팅 참조!