프로그래밍/spring boot

[스프링부트] 실전! 스프링 부트와 JPA 활용2 #1 API 개발 기본 feat. postman 설치 (1)

aSpring 2023. 11. 14. 09:35
728x90
728x90
※ 본 포스팅은 김영한 강사님의 인프런 '실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화' 강의를 들으며 작성한 수강일지 입니다.

 

| API 개발 기본

1. 회원 등록 API
2. 회원 수정 API
3. 회원 조회 API

 

요즘은 화면을 템플린 엔진으로 만드는 경우가 아직 많은데도 있겠지만,

주로 Single Page Application - Vue.js, React 등으로 많이 개발

-> 서버 개발자 입장에서는 예전처럼 서버에서 렌더링해서 내리는 것이 아니라 API 통신을 통해 ..

-> API를 잘 설계하고 개발하는 것이 중요!!

 

0-1. Postman 설치

https://aspring.tistory.com/entry/Postman-Postman-API-Platform-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

 

[Postman] Postman API Platform 설치하기

1. 포스트맨 홈페이지 접속 https://www.postman.com/ Postman API Platform | Sign Up for Free Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create b

aspring.tistory.com

 

 

0-2. API를 위한 폴더 만들기

- 강사님 스타일 : 템플릿 엔진을 사용하여 렌더링 하는 컨트롤러와 api 스타일의 컨트롤러 패키지를 분리

- jpabook/jpashop/api

 

- 패키지를 분리하는 이유? 공통으로 예외처리를 하는 등의 경우 패키지나 구성 단위로 공통 처리를 많이 하게 되는데, API와 화면은 공통처리하는 부분들이 다름.

ex) 화면 : 공통 에러 페이지가 나와야하고, api : 공통 에러 json이 나가야 함

 

1. 회원 등록 API

1. api/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.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

//@Controller @ResponseBody
@RestController // 위 @Controller, @ResponseBody가 합쳐짐 -> data를 JSON으로 바로 xml로 보내자!
@RequiredArgsConstructor
public class MemberApiController {

    private final MemberService memberService;

    @PostMapping("/api/v1/members")
    public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) { // json data를 바로 member에 넣을 수 있음
        Long id = memberService.join(member);
        return new CreateMemberResponse(id);
    }

    @Data
    static class CreateMemberResponse {
        private Long id;

        // 생성d
        public CreateMemberResponse(Long id) {
            this.id = id;
        }
    }
}

 

2. name을 필수값으로 만들기

문제

--> Entity에 들어가 있으므로 화면 validation이 entity에 들어가있는 것

--> 만약 저 name 부분을 username으로 바꾸어 버리면 api 스펙 자체가 변경됨

--> Entity는 굉장히 여러곳에서 사용하는 것, Entity 자체가 바뀌어 버리는 경우가 많기 때문에 API 스펙을 위한 별도의 DTO를 만들어야 함

--> Entity를 이렇게 외부에서 json 오는 것을 바인딩 받는데 쓰면 안됨 -> 궁극적으로 후에 큰 장애가 발생

--> 실무에서는 일반 가입, 소셜 가입 등 여러 경우가 있기 때문에 Entity 하나만으로 감당이 안되는 경우가 많음(entity를 외부에 노출해서 한다는 자체가 XX)

--> entity를 parameter로 받지 말 것, 외부에 노출하지 말 것

 

3. 동일한 이름을 입력

 

 

3. v2 만들기

// 별도의 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;
}

 

별도의 DTO를 만들었을 때 장점

- Entity를 변경해도 API 스펙이 바뀌지 않음

- spec에 맞게 알맞은 validation을 넣으면 됨

- v1은 parameter로 뭐가 넘어올지 모름 -> 넘겨준 값을 다 insert 해버리기도 하고 상황 마다 어떤 데이터가 필요한지도 다름

 

728x90
728x90