[스프링 활용2] 회원 등록 API

atdawn·2024년 6월 25일

SPRING BOOT+JPA

목록 보기
35/49

참고 : [실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화] - 김영한


포스트맨 설치

https://www.postman.com/downloads/

컨트롤러 분리

템플릿 엔진을 사용해서 렌더링하는 컨트롤러와 API 스타일의 컨트롤러 패키지를 분리하자.

  • 공통으로 예외 처리 등을 할 때 보통 패키지나 구성 단위로 공통 처리를 하게 된다.
  • 하지만 API와 View 화면이랑은 공통 처리해야하는 요소가 너무 다르다.
    • 화면은 템플릿 엔진에서 문제가 생기면 에러 화면이 나옴 (공통 에러 HTML)

    • API는 공통 에러용 JSON API 스펙이 나가야 함.

api컨트롤러(api)와 View컨트롤러(controller)를 분리하였다.


MemberApiController

등록 v1 : 요청 값으로 Member 엔티티를 직접 받는다.

...
 @PostMapping("/api/v1/members")
    public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member){
        Long id=memberService.join(member);
        return new CreateMemberResponse(id);

    }

    @Data
    static class CreateMemberResponse{
        private Long id;

        public CreateMemberResponse(Long id) {
            this.id = id;
        }
       ...

@RestController 어노테이션

  • 스프링 프레임워크에서 사용되는 어노테이션으로, 주로 RESTful 웹 서비스를 개발할 때 사용
  • @Controller@ResponseBody 어노테이션을 결합한 것
    • @ResponseBody: 메서드의 반환 값을 HTTP 응답의 본문(body)으로 변환하여 직접 클라이언트에게 반환. 주로 JSON 형식으로 반환
  • 자동 JSON 변환
    • 메서드가 반환하는 객체는 스프링의 메시지 변환기(HttpMessageConverter)에 의해 JSON 또는 XML 등으로 변환
    • 프링 부트의 기본 설정에서는 Jackson 라이브러리를 사용하여 JSON 형식으로 변환

@RequestBody 어노테이션

  • HTTP 요청의 본문(body)에 포함된 Json 데이터를 자바 객체로 변환해주는 역할 (예제에서는 Member으로 변경)
  • RESTful 웹 서비스에서 클라이언트로부터 데이터를 받아 처리하는 데 유용
  • @Valid 또는 @Validated 어노테이션과 함께 사용하여 요청 본문의 데이터에 대한 유효성 검사를 수행

@Data 어노테이션

  • Lombok 라이브러리의 어노테이션
  • getter, setter, toString, equals, hashCode 메서드를 자동으로 생성


포스트맨으로 확인하여보면 정삭적으로 작동하는 것을 확인할 수 있다.


하지만 v1과 같은 방법은 엔티티가 변경되면 API 스펙이 변한다는 큰 문제점을 가지고 있다.
이것을 해결하기 위해서는 API 요청 스펙에 맞추어 별도의 DTO를 파라미터로 받아야 한다. (v2)

❗️API를 만들 때에는 엔티티를 파라미터로 받지 말자❗️ (엔티티 외부 노출 절대 금지)


등록 v2 : API 요청 스펙에 맞추어 별도의 DTO를 파라미터로 받는다.

    @PostMapping("/api/v2/members")
    public CreateMemberResponse saveMemberV2(@RequestBody @Valid CreateMemberRequest request) {
        Member member=new Member();
        member.setName(request.getName());

        Long id=memberService.join(member);
        return new CreateMemberResponse(id);
    }

    @Data
    static class CreateMemberRequest {
        private String name;
    }

    @Data
    static class CreateMemberResponse {
        private Long id;

        public CreateMemberResponse(Long id) {
            this.id = id;
        }
    }
  • CreateMemberRequestMember` 엔티티 대신에 RequestBody와 매핑한다.
  • 엔티티와 프레젠테이션 계층을 위한 로직을 분리할 수 있다.
  • 엔티티와 API 스펙을 명확하게 분리할 수 있다.
  • 엔티티가 변해도 API 스펙이 변하지 않는다.
    • 엔티티 필드명이 변경되더라도 set~~~()부분만 변경해주면 된다.
profile
복습 복습 복습

0개의 댓글