본문 바로가기
개발진행목록/예약 서비스

회원 관련 API 개발

by o3oppp 2024. 10. 17.
회원 등록 API

1. 엔티티를 Request Body에 직접 매핑(요청 값으로 엔티티를 직접 받는 경우)

@Entity
@Getter
@Setter
public class Member {

    @Id
    @GeneratedValue
    @Column(name = "member_id")
    private Long id;

    @NotEmpty
    private String name;
    private String phone;

    @Embedded
    private Address address;

    @OneToMany(mappedBy = "member")
    private List<Reserve> reserves = new ArrayList<>();
}
@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;
    }
}
  • 엔티티에 프레젠테이션 계층을 위한 로직 추가 필요
  • 엔티티에 API 검증을 위한 로직이 추가됨, 그러나 상황에 따라 API별 검증 로직이 다른 경우가 존재할 수도 있음
  • 엔티티 변경 시(ex.Member 클래스의 필드 명 변경 시) API 스펙이 변경

2. 엔티티 대신 DTO를 RequestBody에 매핑(요청 값으로 별도의 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;
    }
}
  • 엔티티와 프레젠테이션 계층을 위한 로직 분리 가능
  • DTO를 여러개 선언하여 API별 검증 로직을 다르게 적용 가능
  • 엔티티와 API 스펙을 명확하게 분리 가능(DTO에 선언된 필드들만 파라미터로 넘어옴)
  • 엔티티가 변해도 API 스펙이 변하지 않음

중요점

  • 엔티티가 변해도 API 스펙이 변하면 안됨

회원 조회 API

1. 응답 값으로 엔티티를 외부에 직접 노출

@GetMapping("/api/v1/members")
public List<Member> membersV1(){
    return memberService.findMembers();
}

API 호출 결과

  • 엔티티의 모든 값이 노출
  • 응답 스펙을 맞추기 위한 로직이 추가됨(@JsonIgnore 등)
  • 엔티티가 변경되면 API 스펙이 변함
  • 컬렉션을 직접 반환하는 경우 API 스펙 변경이 어려움(배열 내 스펙 추가 불가)

2. 응답 값으로 별도의 DTO 사용

@GetMapping("/api/v2/members")
public Result membersV2(){
    List<Member> findMembers = memberService.findMembers();
    List<MemberDto> collect = findMembers.stream()
            .map(m -> new MemberDto(m.getName()))
            .collect(collect.size(), Collectors.toList());

    return new Result(collect);
}
...
@Data
@AllArgsConstructor
static class Result<T> {
    int count; // 필요한 필드 추가
    private T data;
}

@Data
@AllArgsConstructor
static class MemberDto{
    private String name;
}

API 호출 결과

  • 필요한 클래스를 생성한 뒤, 해당 클래스로 컬렉션을 감싸서 향후 필요한 필드 추가 가능(count)

중요점

  • 엔티티를 외부에 노출하며 안됨

'개발진행목록 > 예약 서비스' 카테고리의 다른 글

예약 리스트 조회 API 순환참조 해결  (0) 2024.10.29
예약 조회 API 개발  (0) 2024.10.24
설계  (0) 2024.09.20