JPA

API 개발 기본

MIN우 2023. 1. 17. 16:37
728x90

API 개발 기본

 

회원 등록 API

 

 

회원 등록 API - V1

package jpabook.jpashop.api;


import jpabook.jpashop.domain.Member;
import jpabook.jpashop.service.MemberService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;

@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;
        }
    }
}

엔티티를 RequestBody에 직접 매핑한다.

 

문제점: 엔티티가 변경되면 API의 스펙이 변하게된다.

회원 가입 API- V2

→엔티티 대신 DTO를 RequestBody에 매핑했다.
package jpabook.jpashop.api;


import jpabook.jpashop.domain.Member;
import jpabook.jpashop.service.MemberService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;

@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 CreateMemberResponse{
        private Long id;

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

    @Data
    static class CreateMemberRequest {
        @NotEmpty
        private String name;
    }
}

CreateMemberRequest DTO를 member  엔티티 대신 reqeustBody와 매핑한다.

엔티티와 프레젠테이션 계층이 분리되었다.

엔티티와 API스펙을 명확하게 분리할 수 있다.

엔티티가 변경되어도 API스펙이 변경되지않는다.

 

즉, 실무에서는 API스펙에 엔티티가 노출되어서는 안된다. 각각에 API에 맞는 DTO를 만들어서

엔티티와 분리시키는게 중요하다.

 

 

728x90