API 문서는 MockMvc 테스트 코드 내의 .andDo(document(...)) 블록을 통해 생성됩니다. 이 블록은 restdocs-api-spec 플러그인이 openapi3.json 파일을 생성하는 데 사용하는 명세서입니다.
| 구성 요소 | 역할 |
|---|---|
| Spring REST Docs | MockMvc 테스트 시 API 스펙(요청/응답)을 자동으로 스니펫(snippet)으로 생성 |
| restdocs-api-spec | 생성된 스니펫을 OpenAPI3(JSON) 형식으로 변환 (build/api-spec/openapi3.json) |
| springdoc-openapi-ui | 해당 JSON을 Swagger UI에서 시각화 |
| Swagger UI | 최종 문서 및 API 테스트 UI (운영 서버에서 접근 가능) |
모든 문서는 document() 함수와 resource() 헬퍼를 기반으로 작성됩니다. 예제는 별도로 ResultAction을 저장하고 있으나 mockMvc.perform에 이어서 쓰셔도 무방합니다.
// when
ResultActions resultActions = mockMvc.perform(
post("/api/v1/auth/signup")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)));
// then
resultActions
.andExpect(status().isCreated())
.andExpect(jsonPath("$.data.email").value("[email protected]"))
.andExpect(jsonPath("$.data.username").value("테스트이름"))
.andDo(print());
// docs
resultActions.andDo(document(
"auth-signUp", // 1. 고유 식별자 (도메인-Cotnroller 메서드명)
preprocessRequest(prettyPrint()), // (요청/응답 JSON 예쁘게 포맷)
preprocessResponse(prettyPrint()),
resource( // 2. OpenAPI 스펙 정의 시작
ResourceSnippetParameters.builder()
.summary("회원가입 API") // 3. 요약 (Swagger의 한 줄 설명, API 이름)
.description("...") // 4. 상세 설명
.tag("Auth") // 5. 그룹 태그 (Swagger의 API 그룹)
// --- 스키마 정의 ---
.requestSchema(Schema.schema("Auth.SignUpRequest")) // 6. 요청 스키마 이름
.responseSchema(Schema.schema("Auth.SignUpResponse"))// 7. 응답 스키마 이름
// --- 필드 상세 정의 ---
.requestFields( ... ) // 8. 요청 필드
.responseFields( ... ) // 9. 응답 필드
.build()
)));
.tag("Auth")auth-signUp과 auth-login API를 모두 .tag("Auth")로 지정하면, Swagger UI에서 "Auth"라는 그룹 하위에 함께 묶여 표시됩니다..requestFields(...) 및 .responseFields(...)역할: API의 Request/Response JSON 본문을 필드별로 상세히 문서화합니다. fieldWithPath()를 사용합니다.
기본: fieldWithPath("email").description("사용자 이메일...")
data 래퍼 문서화:
{"data": {...}} 구조이기 때문에, fieldWithPath("data.memberId")처럼 data. 접두사를 붙여 실제 객체 내부를 문서화합니다.선택적 필드 (.optional())
member-updateProfile 예시처럼, 필수 값이 아닌 필드는 .optional()을 붙여 표시합니다..requestFields(
fieldWithPath("username").optional()
.description("사용자 이름 (2~50자, 한글/영문/숫자 가능)")
)
명시적 타입 지정 (.type())
member-updateProfile 예시처럼, .type(JsonFieldType.STRING)을 사용하면 문서에 타입을 명확히 지정할 수 있습니다. (필수는 아니지만 권장됩니다.).responseFields(
fieldWithPath("data.id").type(JsonFieldType.NUMBER)
.description("회원 고유 ID")
)
.requestSchema(...) 및 .responseSchema(...)