이번 강의에서는 기존에 사용하던 RsData(resultCode, msg) 구조를 확장하여
resultCode와 msg만으로는 표현하기 어려운 부가 데이터를 함께 응답으로 내려주는 방법을 다룬다.
특히 프론트엔드와의 협업 관점에서
왜 data 필드가 필요한지,
그리고 현재 구조의 한계와 앞으로의 확장 방향까지 함께 이해할 수 있는 강의였다.
기존에는 조회가 아닌 요청(생성, 수정, 삭제)에 대해
아래와 같은 형태로 응답을 내려주고 있었다.
{
"resultCode": "200-1",
"msg": "1번 댓글이 삭제되었습니다."
}
이 구조는 간단하고 명확하지만, 문제가 하나 있다.
프론트엔드 입장에서 추가 정보가 필요할 경우 매우 불편하다.
예를 들어:
이런 상황에서 프론트가 메시지를 문자열 파싱으로 처리하게 되면:
const id = parseInt(rsData.msg.split("번 댓글이")[0]);
👉 굉장히 위험하고 유지보수하기 힘든 코드가 된다.
그래서 강의에서는 RsData에 data 필드를 추가한다.
public record RsData(
String resultCode,
String msg,
PostCommentDto data
) {
}
이제 응답은 다음과 같은 형태가 된다.
{
"resultCode": "200-1",
"msg": "1번 댓글이 삭제되었습니다.",
"data": {
"id": 1,
"createDate": "...",
"modifyDate": "...",
"content": "댓글 내용"
}
}
댓글 삭제 API는 다음과 같이 변경된다.
@GetMapping("/{id}/delete")
@Transactional
public RsData delete(
@PathVariable int postId,
@PathVariable int id
) {
Post post = postService.findById(postId).get();
PostComment postComment = post.findCommentById(id).get();
postService.deleteComment(post, postComment);
return new RsData(
"200-1",
"%d번 댓글이 삭제되었습니다.".formatted(id),
new PostCommentDto(postComment)
);
}
postComment 객체는 아직 메모리에 살아 있음이제 프론트에서는 이렇게 안전하게 사용할 수 있다.
const id = rsData.data.id;
✔ 문자열 파싱 ❌
✔ 구조화된 데이터 접근 ⭕
✔ 유지보수성 향상 ⭕
강의에서 사용한 resultCode 형식은 다음 의미를 가진다.
200-1
200 : HTTP 상태 코드 (성공)- : 구분자1 : 세부 상황 코드 (댓글 삭제 성공)즉,
HTTP 상태 코드 + 비즈니스 결과 코드를 함께 표현하기 위한 구조이다.
현재 RsData는 이런 형태다.
public record RsData(
String resultCode,
String msg,
PostCommentDto data
) {
}
여기서 한 가지 아쉬운 점이 있다.
❗
data가 댓글 DTO에 고정되어 있음
즉,
범용 응답 객체로 사용하기엔 제한이 있다.
강의에서는 다음 단계로 제네릭 RsData를 사용하게 된다고 설명한다.
개념적으로는 이런 형태다.
public record RsData<T>(
String resultCode,
String msg,
T data
) {
}
이렇게 되면:
RsData<PostDto>RsData<PostCommentDto>RsData<OrderDto>등 모든 응답에 재사용 가능한 범용 응답 객체가 된다.
RsData에 data를 추가함으로써
“메시지 전달용 응답”에서
“프론트와 협업하기 위한 실전 응답 구조”로 한 단계 발전했다.