본 포스팅에서는 Spring Boot에 적용된 Spring REST Docs를 보다 잘 활용하는 방법에 대해 기술합니다!
적용하는 방법은 여기를 참고해 주세요!
request, response 변경하기
기본적으로 나오는 http-request.adoc
과 http-response.adoc
에서 한 두가지 정도를 변경해보자
JSON을 더 보기 좋게
기본적으로 나오는 json은 한 줄로 취급된다. 하지만 이것을 조금 더 이쁘게 출력하고 싶다면 prettyPrint()를 사용하면 된다.
mockMvc.perform(get("/api/v1/data"))
.andDo(print())
.andExpect(status().isOk())
.andDo(document("signup"),
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()));
BEFORE
AFTER
* 주의 : 스프링 부트가 static 파일을 자체 캐싱해두기 때문에 *.adoc
파일을 변경하지 않으면 코드를 바꿨다 하더라도 바뀐 스니펫이 적용되지 않을 수 있다!
URI 변경
modifyUris를 사용하면 request 및 response에 있는 URI를 변경할 수 있다.
mockMvc.perform(get("/api/v1/data"))
.andDo(print())
.andExpect(status().isOk())
.andDo(document("signup"),
preprocessRequest(modifyUris()
.scheme("https")
.host("www.lannstark.com")
.removePort(), prettyPrint()),
preprocessResponse(prettyPrint()));
BEFORE
AFTER
Host가 바꼈고, port가 더이상 보이지 않는다.
하지만 https가 적용되지는 않았다! (뇌피셜: 실제 SSL 설정이 끝나야 적용될 수도 있을 듯 하다)
보다 자세한 내용은 여기를 참고하면 좋다!
추가 스니펫
다양한 형태의 API 인풋과 아웃풋에 대한 docu 작성 방법을 알아보자
쿼리 파라미터
쿼리 파라미터 http://localhost/api/v1?name=이름
아래와 같이 작성하면 된다
mockMvc.perform(get("/api/v1/owner?name=" + name))
...
.andDo(document("somewhere",
requestParameters(
parameterWithName("name").description("조회될 이름")
)));
path 파리미터
path 파리미터 http://localhost/api/이름
아래와 같이 작성하면 된다
mockMvc.perfrom(RestDocumentationRequestBuilders.get("/api/v1/owner/{namne}", name))
...
.andDo(document("somewhere",
pathParameters(
parameterWithName("name").description("조회될 이름")
)));
* 특이사항 : RestDocumentationRequestBuilders
의 method를 사용해야 한다.
JSON request
HTTP body에 JSON 형식으로 데이터를 넣는
아래와 같이 작성하면 된다
mockMvc.perform(post("/"))
...
.andDo(document("somewhere",
requestFields(
fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"),
fieldWithPath("password").type(JsonFieldType.STRING).description("비밀번호")
)));
JSON response 설명
아래와 같이 작성하면 된다
mockMvc.perform(get("/api/v1/owner?name=" + name))
...
.andDo(document("somewhere",
requestParameters(
parameterWithName("name").description("조회될 이름")
),
responseFields(
fieldWithPath("score").type(JsonFieldType.NUMBER).description("점수")
)));
특이사항
만약 배열을 반환하고 있다면 이와 같은 식으로 작성하면 된다.
{
[
{
score: 150
},
{
score: 100
}
]
}
fieldWithPath("[].score").type(JsonFieldType.NUMBER).description("각각의 점수")
배열에 이름이 있다면
{
scoreArray: [
{
score: 150
},
{
score: 100
}
]
}
fieldWithPath("scoreArray.[].score").type(JsonFieldType.NUMBER).description("각각의 점수")
로 처리하면 된다.
스니펫 커스터마이징
이렇게 생긴 스니펫 포맷을 커스터마이징 할 수도 있다. 이전 포스팅과 이번 포스팅의 여기까지를 잘 이해하고 있으면 너무나 잘 설명하고 있는 이 글을 보며 금방 따라할 수 있을 것이다. 따로 포스팅을 작성하지는 않을 계획이다.
주의할 점
Rest docs와 관련하여 삽질하다가 알아낸건데, 만약 API가 객체를 반환하지 않는데 responseFields
를 사용한다면 ClassCastException
가 계속 나올 것이다!
예를 들어
@RequestMappin(value = "", method = RequestMethod.GET)
public boolean amISuccess() {
return true;
}
이런 API가 있고 이 API를 대상으로
mockMvc.perform(get("/"))
.andDo(print())
.andExpect(status().isOk())
.andDo(document("test", responseFields(
fieldWithPath("success").type(JsonFieldType.STRING).description("성공 실패 여부")
)));
와 같은 코드를 작성한다면 ClassCastException
만 보게 될 것이다... (2019년 7월 24일 최신 버전 기준)
해결 방법은 API가 객체를 반환하게 해야 한다
* 추가로, String 객체도 안된다
String 객체를 반환하는 API에 responseFields를 설정하려고 하면content as it could not be parsed as JSON or XML
만 보게 될 것이다.
'개발 공부 기록하기 > 04. Spring & Spring Boot' 카테고리의 다른 글
There is no EC2 meta data available, because the application is not running in the EC2 environment 해결 (1) | 2020.09.19 |
---|---|
Failed to instantiate StackNameProvider 해결 (1) | 2020.09.18 |
Spring Boot Interceptor에서 권한 관리하기 I (HttpServletRequest getInputStream 여러번) (0) | 2020.03.18 |
Spring Boot SQL 보기 옵션 총 정리 (4) | 2019.07.30 |
Spring REST DOCS를 Spring Boot에 적용하기 (1) (3) | 2019.07.25 |