일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 네트워크 설정
- 서버설정
- 자료구조와 함께 배우는 알고리즘 입문
- ㅒ
- 리눅스
- iterator
- GIT
- network configuration
- 코드로배우는스프링부트웹프로젝트
- 자바편
- 데비안
- 스프링부트핵심가이드
- 알파회계
- 목록처리
- 이터레이터
- 코드로배우는스프링웹프로젝트
- 스프링 시큐리티
- Kernighan의 C언어 프로그래밍
- /etc/network/interfaces
- d
- 티스토리 쿠키 삭제
- 자료구조와함께배우는알고리즘입문
- baeldung
- 처음 만나는 AI 수학 with Python
- 친절한SQL튜닝
- resttemplate
- 처음 만나는 AI수학 with Python
- 페이징
- 선형대수
- 구멍가게코딩단
- Today
- Total
bright jazz music
blog13: Spring REST Docs3 - 커스터마이징 본문
지금까지 만든 것은 글 조회와 등록의 구분이 되지 않았음. 따라서 정리 필요.
글 조회는 post-inquiry로 변경, 글 등록은 post-create로 변경
//PostControllerDocTest.java
package com.endofma.blog.controller;
import com.endofma.blog.domain.Post;
import com.endofma.blog.repository.PostRepository;
import com.endofma.blog.request.PostCreate;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.payload.PayloadDocumentation;
import org.springframework.restdocs.request.RequestDocumentation;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest //부트의 경우 이걸 사용. 이 안에 SpringExtension이 포함되어 있다.
@AutoConfigureMockMvc//추가
@AutoConfigureRestDocs(uriScheme = "https", uriHost = "api.blog.com", uriPort = 443)
@ExtendWith(RestDocumentationExtension.class) //부트의 경우
//@ExtendWith({RestDocumentationExtension, SpringExtension.class}) //Spring MVC의 경우는 이렇게
public class PostControllerDocTest {
//테스트 수행 전 셋업
@Autowired
private MockMvc mockMvc;
@Autowired
private PostRepository postRepository;
@Autowired
private ObjectMapper objectMapper;
//JUnit자체적으로 주입하기 때문에 생성자를 통해 주입하면 아래 에러 발생
//org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter
//public PostControllerDocTest(PostRepository postRepository){
// this.postRepository = postRepository;
//}
//asciidoc에 맞는 설정을 가지고 mockMvc를 설정하는 코드
// @BeforeEach
// void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
// this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
// .apply(documentationConfiguration(restDocumentation)) //덮어써짐.
// .build();
// }
@Test
@DisplayName("글 단건 조회 테스트")
void test1() throws Exception {
//given
Post post = Post.builder()
.title("제목")
.content("내용")
.build();
postRepository.save(post);
//expected
// this.mockMvc.perform(get("/")
// this.mockMvc.perform(get("/posts/{postId}", 1L)
this.mockMvc.perform(RestDocumentationRequestBuilders.get("/posts/{postId}", 1L)
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andDo(document("post-inquiry", //글 조회
RequestDocumentation.pathParameters( //PathParameter를 사용할 거면 ResDocumentationRequestBuilder 사용 권함
RequestDocumentation.parameterWithName("postId").description("게시글 ID")
//path-parameter
),
PayloadDocumentation.responseFields(
PayloadDocumentation.fieldWithPath("id").description("게시글 ID"),
PayloadDocumentation.fieldWithPath("title").description("제목"),
PayloadDocumentation.fieldWithPath("content").description("내용")
)
));
}
@Test
@DisplayName("글 등록 테스트")
void test2() throws Exception {
PostCreate request = PostCreate.builder()
.title("Spring Rest Docs test title") //제목에 바보 포함 불가
.content("부림동")
.build();
String json = objectMapper.writeValueAsString(request);
this.mockMvc.perform(RestDocumentationRequestBuilders.post("/posts")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json)) //objectMapper로 변환한 json
.andDo(print())
.andExpect(status().isOk())
.andDo(document("post-create", //글 등록
PayloadDocumentation.requestFields(
PayloadDocumentation.fieldWithPath("title").description("제목"),
PayloadDocumentation.fieldWithPath("content").description("내용")
)
));
}
}
asciidoctor 실행

아래와 같이 index.adoc을 수정
// index.adoc
//{snippetes}: /build/generated-snippets
= 블로그 API
:toc:
== 글 단건 조회
=== 요청
include::{snippets}/post-inquiry/http-request.adoc[]
include::{snippets}/post-inquiry/path-parameters.adoc[]
=== 응답
include::{snippets}/post-inquiry/http-response.adoc[]
include::{snippets}/post-inquiry/response-fields.adoc[]
include::{snippets}/post-inquiry/curl-request.adoc[]
// include::{snippets}/index/httpie-request.adoc[]
// include::{snippets}/index/request-body.adoc[]
// include::{snippets}/index/response-body.adoc[]
== 글 작성
=== 요청
include::{snippets}/post-create/http-request.adoc[]
include::{snippets}/post-create/request-fields.adoc[]
=== 응답
include::{snippets}/post-create/http-response.adoc[]
include::{snippets}/post-create/curl-request.adoc[]
asciidoctor 실행 후 서버 재기동


-------------------
여기서부터 커스터마이징.
만약 content를 필수가 아닌 옵션으로 하고자 한다면.
커스터마이징 방법은 공식문서에 나와있다.
https://docs.spring.io/spring-restdocs/docs/2.0.7.RELEASE/reference/html5/
src/test/resources/org/springframework/restdocs/templates/asciidoctor

request-fields.snippet의 내용. title은 빼버렸다. Constraints와 contraints는 각각 Optional 과 optional로 변경. 이는 mustache문법이다.
|===
|Path|Type|Description|Optional
{{#fields}}
|{{path}}
|{{type}}
|{{description}}
|{{optional}}
{{/fields}}
|===
왼쪽 정렬 필수!!
//PostControllerDocTest.java
@SpringBootTest //부트의 경우 이걸 사용. 이 안에 SpringExtension이 포함되어 있다.
@AutoConfigureMockMvc//추가
@AutoConfigureRestDocs(uriScheme = "https", uriHost = "api.blog.com", uriPort = 443)
@ExtendWith(RestDocumentationExtension.class) //부트의 경우
//@ExtendWith({RestDocumentationExtension, SpringExtension.class}) //Spring MVC의 경우는 이렇게
public class PostControllerDocTest {
//테스트 수행 전 셋업
@Autowired
private MockMvc mockMvc;
@Autowired
private PostRepository postRepository;
@Autowired
private ObjectMapper objectMapper;
//JUnit자체적으로 주입하기 때문에 생성자를 통해 주입하면 아래 에러 발생
//org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter
//public PostControllerDocTest(PostRepository postRepository){
// this.postRepository = postRepository;
//}
//...
@Test
@DisplayName("글 등록 테스트")
void test2() throws Exception {
PostCreate request = PostCreate.builder()
.title("Spring Rest Docs test title") //제목에 바보 포함 불가
.content("부림동")
.build();
String json = objectMapper.writeValueAsString(request);
this.mockMvc.perform(RestDocumentationRequestBuilders.post("/posts")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json)) //objectMapper로 변환한 json
.andDo(print())
.andExpect(status().isOk())
.andDo(document("post-create", //글 등록
PayloadDocumentation.requestFields(
PayloadDocumentation.fieldWithPath("title").description("제목"),
PayloadDocumentation.fieldWithPath("content").description("내용").optional() //optional추가
)
));
}
}
content에 .optional() 추가
이렇게 하면 빌드할 때 src/test/.... /request-fields.snippets를 참고로 하여 request-fields.adoc 문서를 만들 것이다.
asciidoctor 실행
서버 재기동 후 확인
그런데 값이 늘어나서 Optional의 항목이 길게 늘어지면 보기에 헷갈린다.
따라서 mustache의 문법을 사용해서 true일 때만 보여주도록 한다.
|{{#optional}}Y{{/optional}}
위 문법을 사용해서 request-field.snippet을 수정하고 asciidoctor 실행 -재기동
|===
|Path|Type|Description|Optional
{{#fields}}
|{{path}}
|{{type}}
|{{description}}
|{{#optional}}Y{{/optional}}
{{/fields}}
|===
아래와 같이 true인 것만 보여주도록 변경되었다.
---------------------
나만의 칼럼을 만들고자 한다면.
asciidoctor 실행
따라서 request-fields.snippet을 수정해준다. (mustache 문법 입력됨)
서버 재기동 후 확인
-----------------------------------
문서가 안 예뻐서 문서 자체를 꾸미고자 할 때
아래는 전문
// index.adoc
//{snippetes}: /build/generated-snippets
= 블로그 API
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 2
:sectlinks:
== 글 단건 조회
=== 요청
include::{snippets}/post-inquiry/http-request.adoc[]
include::{snippets}/post-inquiry/path-parameters.adoc[]
=== 응답
include::{snippets}/post-inquiry/http-response.adoc[]
include::{snippets}/post-inquiry/response-fields.adoc[]
include::{snippets}/post-inquiry/curl-request.adoc[]
// include::{snippets}/index/httpie-request.adoc[]
// include::{snippets}/index/request-body.adoc[]
// include::{snippets}/index/response-body.adoc[]
== 글 작성
=== 요청
include::{snippets}/post-create/http-request.adoc[]
include::{snippets}/post-create/request-fields.adoc[]
=== 응답
include::{snippets}/post-create/http-response.adoc[]
include::{snippets}/post-create/curl-request.adoc[]
asciidoctor 실행 후 서버 재기동
아래와 같이 바뀌었다.
'Projects > blog' 카테고리의 다른 글
blog15 : Git 자주 쓰는 명령어 예제 1 (0) | 2023.01.29 |
---|---|
blog14 : Github SSH 설정, 프로젝트 올리기 (0) | 2023.01.29 |
blog13: Spring REST Docs2 - 요청, 응답필드 (0) | 2023.01.16 |
blog13: Spring REST Docs 1 -기본설정 (0) | 2023.01.15 |
blog12: 예외처리 4 (0) | 2023.01.14 |