반응형
문제 상황
기존에 Notion으로 API 문서를 작성하고 관리해왔으나 여러 가지 문제점이 존재하였다.
- HTTP Request, Response에 대한 스펙을 직접 작성해야 한다.
- 따라서 코드를 수정해서 결과가 변경되면 매번 문서의 내용을 고쳐야한다.
- 100% 정확한 문서라고 단정할 수 없다.
- 요청과 응답 양식을 수정하면서 변수명이 수정되거나 변수가 추가되는 등 작업이 수행되면, 그때마다 문서도 수정해야 한다.
- 단적인 예로, Response 양식에서 Dto 객체 명을 followingUserInfoDto에서 followingUserDto로 변경하였는데 API 문서에 업데이트하는 것을 빠뜨려서, 프론트 측에서 데이터를 제대로 받지 못하는 문제가 발생하였다. (아래 사진)
시도 1: Swagger 도입
따라서 Swagger를 도입하였으나, Notion API와 비슷한 문제가 발생하였다.
- HTTP Request, Response에 대한 스펙을 직접 작성해야 한다.
- 따라서 코드를 수정해서 결과가 변경되면 매번 Update해야 한다.
- 이 부분이 Notion을 사용할 때와 동일하였으므로, 근본적인 원인을 해결하지는 못하였다.
- 프로덕션 코드에 침투적이다.
- 이를 방지하기 위해, 따로 Annotation을 만들어서 관리하였으나, 코드를 수정해서 결과가 변경되면 매번 Update해야 한다는 단점은 여전히 존재한다.
해결: Spring Rest Docs 도입
- Spring Rest Docs의 경우 테스트 코드를 작성해야만 API 문서가 작성되는데, 나는 이미 테스트 코드를 어느 정도 작성하였기 때문에 빨리 도입을 할 수 있을 것으로 생각하였음
- 또한 asciidoc 문법으로 작성하면 자동으로 API 문서가 생성되는 점이 편리하다.
- 아래 공식문서를 참고한 결과, 초기 세팅이 그렇게 복잡하지 않아 보였다.
- https://docs.spring.io/spring-restdocs/docs/current/reference/htmlsingle/#documenting-your-api-request-parts
프로젝트에서 수행한 작업
- API 문서인 index.adoc 파일 생성 및 관리
- Spring Rest Docs Configuration
- ControllerTest와 RestDocsTest 도메인을 분리해서, 즉 패키지를 분리해서 각각 관리하도록 구조를 변경하였다.
- ControllerTest의 경우에는 body의 모든 응답 결과를 테스트한다.
- RestDocsTest의 경우에는 http status(code)의 결과만 테스트한다.
/** ControllerTest 예시 **/
// then
mvc.perform(MockMvcRequestBuilders.post("/api/follow/create")
.contentType(MediaType.APPLICATION_JSON)
.content(content))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.code", is(SuccessCode.FOLLOW_CREATED.getCode())))
.andExpect(jsonPath("$.message", is(SuccessCode.FOLLOW_CREATED.getMessage())))
.andExpect(jsonPath("$.data", is(Matchers.nullValue()))) // Check for null
.andDo(print());
verify(followService, times(1)).createFollow(followCreateRequest.toServiceRequest());
/** RestDocsTest의 예시 **/
// then
mockMvc.perform(RestDocumentationRequestBuilders.post("/api/follow/create")
.contentType(MediaType.APPLICATION_JSON)
.content(content))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.code", is(SuccessCode.FOLLOW_CREATED.getCode())))
.andDo(print())
.andDo(document("api/follow/create/201/true",
requestFields(
fieldWithPath("userNickname").type(JsonFieldType.STRING)
.description("사용자 닉네임"),
fieldWithPath("followNickname").type(JsonFieldType.STRING)
.description("사용자가 팔로우 요청을 보내는 닉네임")
),
responseFields(
fieldWithPath("code").type(JsonFieldType.NUMBER).description("응답 코드"),
fieldWithPath("message").type(STRING).description("응답 메시지"),
fieldWithPath("data").type(JsonFieldType.NULL).description("응답 데이터")
)
));
반응형
'멘질멘질] 2023 졸업 프로젝트' 카테고리의 다른 글
Spring Boot] STOMP 프로토콜 (0) | 2023.09.01 |
---|---|
AWS] 컨테이너 이미지를 사용한 AWS Lambda 배포 (0) | 2023.08.24 |
Junit5] @CreatedDate NullPointer Exception (0) | 2023.07.22 |
Ubuntu] Docker 용량 줄이기 (0) | 2023.06.25 |
Ubuntu] Next.js Dockerfile 경량화(Optimize) (0) | 2023.06.22 |