회원 등록 API

HotFried·2023년 11월 23일
0

템플릿 뷰를 반환하는 컨트롤러와 api 방식의 컨트롤러의 패키지를 분리!
-> 예외 처리 방식이 다르기 때문
ex. api 방식은 json 형식으로 응답을 보낸다.


V1 엔티티를 Request Body에 직접 매핑

@RestController
@RequiredArgsConstructor
public class MemberApiController {

    private final MemberService memberService;

    @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 : @Controller + @ResponseBody
@ResponseBody : 데이터를 json, xml로 보낼 때 사용
@RequestBody : json 데이터를 객체로 변경
@Valid : javax validation을 체크해준다.


문제점 & 결론

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

  • 엔티티에 프레젠테이션 계층을 위한 로직이 추가된다.

    • 엔티티에 API 검증을 위한 로직이 들어간다.
    public class Member {
      @NotEmpty
      private String name;
    }
    • 만약 회원 엔티티를 위한 API가 다양하게 만들어진다면,
      한 엔티티에 각각의 API를 위한 모든 요청 요구사항을 담는 것은 한계가 있다.
  • 엔티티가 변경되면 API 스펙이 변한다.

-> API 요청 스펙에 맞추어 별도의 DTO를 파라미터로 받는다.


V2 엔티티 대신에 DTO를 RequestBody에 매핑

@RestController
@RequiredArgsConstructor
public class MemberApiController {

    private final MemberService memberService;

    @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와 매핑
  • Entity와 프레젠테이션 계층을 위한 로직을 분리
  • Entity와 API 스펙을 명확하게 분리
  • Entity가 변해도 API 스펙이 변하지 않음
  • Entity를 API 스펙에 노출하지 말자

참고 :

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

profile
꾸준하게

0개의 댓글