실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
수업을 듣고 정리한 글입니다.
회원 등록 API
@RestController = @Controller + @ResponseBody(데이터를 JSON or xml로 바로 보내기) +...
@RequestBody : request의 body를 통째로 전달(JSON or XML 요청시 유용)
@ResponseBody: http요청 body를 통째로 변환해서 자바 객체로 전달받을 수 있다.
출처: https://cheershennah.tistory.com/179
@Valid : service 단이 아닌 객체 안에서 들어오는 값에 대해 검증할 수 있다.
출처 & 자세한 내용: https://jyami.tistory.com/55
MemberApiController.java
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;
@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;
}
}
}
member를 join하여 CreateMemberResponse 객체를 반환하는 api
Postman으로 테스트
요청을 보내면 자동생성된 id와 "hello"이름을 가진 Member가 생성된다.
join한 이후에 CreateMemberResponse 객체를 만들어 반환한다.
CreateMemberResponse는 id만 가진 객체이다.
@Data : @Getter + @Setter + @RequiredNoArgsConstructor... (종합)
@NotEmpty 어노테이션을 붙이면 요청시 무조건 그 변수값을 지정해주어야한다.
결과
그러나 이렇게 하면 조금만 entity의 파라미터 값을 수정하면(ex) name -> username) API Spec 이 바뀌어버리기때문에 큰 문제가 발생할 수 있다.
=> API 만들때는 Entity를 파라미터로 받으면 안된다. 또한 Entity를 웹에 노출해서도 안된다.
=> 그래서 DTO가 필요하다.
더 나은 API 구조
요청을 CreateMemberRequest 객체로 받는다.(DTO)
Member 객체를 생성하여 요청값을 넣어준다.
파라미터에는 현재 name만 있지만 주소 등등 Member의 속성값을 추가로 넣어줘도 된다.
이렇게 하면 name->username으로 값을 바꿔도 중간에 매핑해주는 객체가 있기때문에 컴파일 오류가 난다.
(setName이 아니라 setUsername이라고 setter 이름을 바꿔주어야함..entity 필드명 자체가 바뀌는 일은 없다.)
=> entity와 API Spec이 분리된다.
회원 수정 API
PUT: 멱등하다(같은 것을 여러번 호출해도 결과가 같다) - 전체 업데이트 시 사용
PATCH, POST - 부분 업데이트시 사용
우리는 그냥 PUT 쓴다.
REST API Style 찾아보기
@PathVariable: URI의 값이 파라미터에 매핑된다.
출처: https://sarc.io/index.php/development/1145-pathvariable
MemberApiController - UpdateApi 만들기
요청 dto와 응답 dto를 각각 만드는게 좋다.(수정은 일부분에서 일어나므로)
update하고 entity를 반환해도 좋지만 그러면 영속성이 사라진 객체를 다시 쿼리하는 그런 느낌(완전히 이해는 못함)이므로 반환하지말고 그냥 조회해서 쓰자.
MemberService - update 메서드 만들기
테스트
post 요청 - 회원 등록
put 요청 - 회원 수정
회원 조회 API
application.yml 에서 auto-ddl:none 으로 해준다. (테이블 drop안하고 계속 데이터 사용할 수 있도록)
MemberApiController - 조회 API
조회 결과
orders는 주문 정보인데, API의 응답 데이터가 순수하게 Member 정보만 뿌리고 싶다면 @JsonIgnore을 쓰면 된다.
조회 결과
그러나 entity에 presentation을 위한 로직이 녹아들어가는것은 안좋다...
(어떤것은 orders가 필요할 수도 있으므로 -> 양방향 의존관계 발생가능)
그리고 entity가 직접 반환되면 후에 API Spec을 변경하기 어렵다.
entity 직접 반환하여 노출하지말자.
더 나은 방법
member 스트림을 memberDto 스트림으로 바꾸고(map) 리스트로 반환한 다음 -> Result로 묶기(Result로 안묶으면 배열타입으로 나간다.)
조회 결과
=> api spec이 dto와 매핑된다.
api spec을 추가하고싶으면 Result에 추가해주면 된다.
결과
'Spring > 웹 애플리케이션 개발' 카테고리의 다른 글
웹 애플리케이션 개발 - 웹 개발 (0) | 2023.04.01 |
---|---|
웹 애플리케이션 개발 -도메인 개발 (1) | 2023.03.31 |
웹 애플리케이션 개발 - 시작~설계 (1) | 2023.03.29 |