Spring Boot - 8

현곤·2024년 12월 20일
public class RsData<T> {
	private String resultCode;
    private String msg;
    private T data;
    
    public RsData(String resultCode, String msg) {
        this(resultCode, msg, null);
    }
}

T???? 신기하다

TObject 나 똑같다

T 라고 쓰는 건 관행이다 기억하기

new RsData<Long>();

PostWirteBody

PostDeleteBody

PostModifyBody

조회(GET)를 제외한 모든 액션 메서드의 리턴 타입에 RsData는 필수다.

  • resultCode : 꼭 필요함 자세한 결과를 알 수 있다.

  • msg(message) : 꼭 필요함 결과에 대한 메세지를 알 수 있다.

  • data(Body) : 경우에 따라 필요 없지만, 그래도 추가해두는 게 좋다.

상태코드 분류

상태코드설명
1xx정보 전달
2xx성공
3xx리다이렉션
4xx클라이언트(고객 잘못) 오류
5xx서버(서버 잘못) 오류

주요 상태코드

상태코드설명
200성공
201생성됨
204성공했지만 응답 데이터 없음
400잘못된 요청
401인증 필요
403권한 없음
404리소스를 찾을 수 없음
500서버 내부 오류
503서비스 이용 불가

대충 무신사나 요런 곳은 이렇게만 사용한다

상태코드설명
200성공
400잘못된 요청
500서버 내부 오류

어차피 resultCode 로 알 수 있어서 요렇게만 나타내도 됨

ResponseEntity<[return code]>

@JsonProperty

이걸 왜 쓰는가

  1. Java랑 Json이랑 서로 필드명이 다를 때

    • @JsonProperty 를 사용하면 JSON 필드와 Java 필드 간의 이름 매칭을 쉽게 설정할 수 있다.
    • Java 필드명은 일반적으로 카멜 케이스를 따르는데,
      Json 필드명은 스네이크 케이스나 특정 네이밍 규칙을 따르는 경우가 많다.
      - 예시 createDatetime (Json 필드명) ↔ createDate(Java 필드명)
  2. API 요구사항에 따른 명명 규칙을 충족시킬 때

    • API 설계에서 클라이언트가 요구하는 JSON 필드명이 CreateDatetime 이라면,
      이 요구사항을 만족시키기 위해 @JsonProperty 를 사용
  3. 유지보수성을 위해

    • Java 필드명 (createDate) 을 변경하지 않아도 JSON 출력 필드명을
      명확히 제어할 수 있어 유지보수가 용이

직렬화, 역직렬화 과정에서 JSON 필드명, Java 객체 필드명을 매핑하기 위해

JSON 직렬화 (객체에서 JSON)

  • createDate -> createDateTime 필드명으로 변환

JSON 역직렬화 (JSON에서 객체)

  • JSON에서 createDateTime 필드를 찾아, createDate 에 매핑

내가 생각하는 DTO

Entity 로 응답을 하면 보안적인 문제도 있고,

모든 데이터를 꺼내다보니 성능이 저하된다.

그래서 DTO를 사용하는 것이 좋다.

유지보수가 편리하고, 클라이언트가 원하는 것만 꺼내다보니 성능적으로도 좋다!

사용하는 방법은, 클래스를 정의하는 것

@Getter
public class PostDto {
    private long id;
    @JsonProperty("createDatetime")
    private LocalDateTime createDate;
    @JsonProperty("modifiedDatetime")
    private LocalDateTime modifyDate;
    private String title;
    private String content;

    public PostDto(Post post) {
        this.id = post.getId();
        this.createDate = post.getCreateDate();
        this.modifyDate = post.getModifyDate();
        this.title = post.getTitle();
        this.content = post.getContent();
    }
}

이렇게 클래스를 정의한 다음 컨트롤러에서 변환하는 방법을 사용

	@GetMapping
    public List<PostDto> getItems() {
        return postService
                .findAllByOrderByIdDesc()
                .stream()
                .map(PostDto::new)
                .toList();
    }

    @GetMapping("/{id}")
    public PostDto getItem(
            @PathVariable long id
    ) {
        return postService.findById(id)
                .map(PostDto::new)
                .orElseThrow();
    }

근데 이렇게 하면 서비스 로직이 컨트롤러에 포함하게 되는데

컨트롤러가 서비스를 많이 사용하게 되면서 컨트롤러의 코드 양이 많아지고,

유지보수가 어려워진다

그럼 서비스에서 사용하면?

컨트롤러에 있는 저 코드를 그대로 들고와서 서비스에 적용하면 된다

그러고 그냥 컨트롤러는 서비스에 있는 거 들고오면 되는 간딴한 방법

profile
코딩하는 곤쪽이

0개의 댓글