Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 백준
- JPA
- 스프링 부트
- Spring Security
- application.properties
- 리소스핸들러
- HttpMessageConverters
- Application Event
- 백트래킹
- rest api
- EnableAutoConfiguration
- JsonSerializer
- WebApplication Type
- 리소스 서버
- OAuth2
- @Profile
- 정적 리소스
- @ConfigurationProperties
- 외부설정
- cors
- 다익스트라
- AuthenticationPrincipal
- HATEOAS
- Application Argument
- 브루트포스
- 알고리즘
- 백기선
- 스프링부트
- Application Runner
- webjar
Archives
- Today
- Total
아카이브
[스프링 기반 REST API 개발] Request/Response 필드와 헤더 문서화하기 본문
API 문서 만들기
- 요청 본문 문서화: request-body
- 응답 본문 문서화: response-body
- 링크 문서화: links
- self
- query-events
- update-event
- profile 링크 추가
- 요청 헤더 문서화: requestHeaders
- 요청 필드 문서화: requestFields
- 응답 헤더 문서화: responseHeaders
- 응답 필드 문서화: responseFields
links : linkWithResl()
~Headers : headerWithName
~Fields : fieldWithPath
@Test
@DisplayName("정상적으로 이벤트를 생성하는 테스트")
void createEvent() throws Exception {
EventDto eventDto = EventDto.builder()
.name("Spring")
.description("REST API dev with Spring")
.beginEnrollmentDateTime(LocalDateTime.of(2020, 12, 25, 12, 12))
.closeEnrollmentDateTime(LocalDateTime.of(2020, 12, 26, 12, 12))
.beginEventDateTime(LocalDateTime.of(2020, 12, 27, 12, 12))
.endEventDateTime(LocalDateTime.of(2020, 12, 28, 12, 12))
.basePrice(100)
.maxPrice(200)
.limitOfEnrollment(1000)
.location("D2 Factory")
.build();
this.mockMvc.perform(post("/api/events/")
.header(HttpHeaders.AUTHORIZATION, getBearerToken(true))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaTypes.HAL_JSON)
.content(objectMapper.writeValueAsString(eventDto))
)
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("id").exists())
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_JSON_VALUE))
.andExpect(jsonPath("free").value(false))
.andExpect(jsonPath("offline").value(true))
.andExpect(jsonPath("eventStatus").value(Matchers.not(EventStatus.DRAFT)))
.andExpect(jsonPath("_links.self").exists())
.andExpect(jsonPath("_links.query-events").exists())
.andExpect(jsonPath("_links.update-event").exists())
.andExpect(jsonPath("_links.profile").exists())
.andDo(document("create-event",
// 링크 문서화
links(
linkWithRel("self").description("link to self"),
linkWithRel("query-events").description("link to query events"),
linkWithRel("update-event").description("link to update an existing event"),
linkWithRel("profile").description("link to profile")
),
// 요청 헤더
requestHeaders(
headerWithName(HttpHeaders.ACCEPT).description("Accept header"),
headerWithName(HttpHeaders.CONTENT_TYPE).description("Content type header")
),
// 요청 필드
requestFields(
fieldWithPath("name").description("name of new event"),
fieldWithPath("description").description("description of new event"),
fieldWithPath("beginEnrollmentDateTime").description("beginEnrollmentDateTime of new event"),
fieldWithPath("closeEnrollmentDateTime").description("closeEnrollmentDateTime of new event"),
fieldWithPath("beginEventDateTime").description("beginEventDateTime of new event"),
fieldWithPath("endEventDateTime").description("endEventDateTime of new event"),
fieldWithPath("basePrice").description("basePrice of new event"),
fieldWithPath("maxPrice").description("maxPrice of new event"),
fieldWithPath("limitOfEnrollment").description("limitOfEnrollment of new event"),
fieldWithPath("location").description("location of new event")
),
// 응답 헤더
responseHeaders(
headerWithName(HttpHeaders.LOCATION).description("Location header"),
headerWithName(HttpHeaders.CONTENT_TYPE).description("Content type")
),
// 응답 필드
relaxedResponseFields(
fieldWithPath("id").description("id of new event"),
fieldWithPath("name").description("name of new event"),
fieldWithPath("description").description("description of new event"),
fieldWithPath("beginEnrollmentDateTime").description("beginEnrollmentDateTime of new event"),
fieldWithPath("closeEnrollmentDateTime").description("closeEnrollmentDateTime of new event"),
fieldWithPath("beginEventDateTime").description("beginEventDateTime of new event"),
fieldWithPath("endEventDateTime").description("endEventDateTime of new event"),
fieldWithPath("basePrice").description("basePrice of new event"),
fieldWithPath("maxPrice").description("maxPrice of new event"),
fieldWithPath("limitOfEnrollment").description("limitOfEnrollment of new event"),
fieldWithPath("location").description("location of new event"),
fieldWithPath("free").description("it tells is this event if free or not"),
fieldWithPath("offline").description("it tells is this event is offline event or not"),
fieldWithPath("eventStatus").description("event status"),
fieldWithPath("_links.self.href").description("link to self"),
fieldWithPath("_links.query-events.href").description("link to query events"),
fieldWithPath("_links.update-event.href").description("link to update an existing event"),
fieldWithPath("_links.profile.href").description("link to profile")
)
))
;
}
target/generated-snippets 위치에 doc-name 에 맞게 adoc이 생성된다.
Spring REST Doc는 문서화를 하지않은 필드가 있으면 강제하기 위해 테스트를 실패시킨다.
이를 relaxed~접두어가 붙은 method로 통과시킬 수 있지만 가급적 지양한다.
'Spring > 스프링 기반 REST API 개발' 카테고리의 다른 글
[스프링 기반 REST API 개발] 테스트용 DB와 설정 분리하기 (0) | 2021.01.06 |
---|---|
[스프링 기반 REST API 개발] Spring REST Docs 문서 빌드하기 (0) | 2021.01.06 |
[스프링 기반 REST API 개발] Spring REST Docs 소개, 자동 설정 및 커스터마이징 (0) | 2021.01.06 |
[스프링 기반 REST API 개발] Spring HATEOAS 적용 (0) | 2021.01.06 |
[스프링 기반 REST API 개발] 입력 받을 수 없는 값의 경우 Bad Request (0) | 2021.01.05 |