[56일차]Asciidoc, document()

유태형·2022년 7월 18일
0

코드스테이츠

목록 보기
56/77

오늘의 목표

  1. Asciidoc
  2. document()



내용

Asciidoc

Asciidoc은 Spring Rest Docs를 통해 생성되는 텍스트 기반 문서입니다.

Asciidoc은 기술 문서 작성을 위해 설계된 마크다운 언어입니다. HTML, PDF, EPUB 등 다양한 형식으로 변환될 수 있습니다.



목차

= 문서 제목
:sectnum:
:toc: left
:toclevels: 1~6
:toc-title: 타이틀
:source-highlighter: prettify

asciidoc은 여러 속성들로 이루어질 수 있습니다.

  • :sectnum: : 각 섹션에 넘버링을 표시합니다.
  • :toc:: left : 문서의 목차를 어디에 구성할 것인지 지정합니다. left는 목차를 왼쪽으로 표시합니다.
  • :toclevels: 1~6 : 목차에 표시할 각 섹션의 제목의 level(HTML기준 h1~h6)을 지정합니다. 4로 지정할시 <h4> 까지의 제목을 목차에 포함시킵니다.
  • :toc-title: 타이틀 : 목차의 제목을 지정할 수 있습니다.
  • source-highlighter: prettify : 소스코드 하이라이트를 지정합니다. prettify로 지정한 예시입니다.
***
문단의 제목

	문단 내용입니다. 문단 내용입니다. 문단 내용입니다. 문단 내용입니다. 문단 내용입니다. 문단 내용입니다. 문단 내용입니다. 문단 내용입니다. 문단 내용입니다. 문단 내용입니다.
CAUTION: 경고!
***
  • *** : 수평선을 긋습니다. HTML의 <hr>과 동일한 기능입니다.
  • 문단의 제목 다음에 한 라인을 띄우고 한 칸 들여쓰기 하면 박스 문단을 사용할 수 있습니다.
  • CAUTION: : 경고문구를 표시합니다. NOTE:, TIP:, IMPORTANT:, WARNING:등을 사용할 수 있습니다.


URL, 이미지

  • HTTP, HTTPS, FTP, IRC, MAILTO, xxx@mail.com : asciidoc에서 자동으로 URL Schema를 자동으로 인식하여 링크가 설정됩니다.
  • image::링크 : API문서에 이미지를 추가할 수 있습니다.


문서 스니핏

Spring Rest Docs 테스트케이스를 통과하면 build/generated-snippets/식별자 디렉터리에 .adoc 스니핏 문서가 생성됩니다. 하지만 각각의 스니핏 문서를 일일이 확인하는 것은 번거로울 뿐더러 협업을 수행하는 다른 개발자 및 직원들이 이해하기 어려우므로 HTML로 하나의 문서로 통합시키는 것이 훨씬 가독성과 의사소통에 유리할 것입니다.

build.gradle에 task에 명령을 지정하면 Ascidoctor가 내부적으로 index.adocindex.html로 변환 시켜줄수 있으므로 index.adoc에 마크다운 언어를 입력하여 index.html에서 마크업 언어로 변환 될 수 있습니다.

각각의 스니핏을 통합시킬 index.adoc에 포함시키는 방법은 아래와 같습니다.

.스니핏1
include::{snippets}/식별자/스니핏1.adoc[]

.스니핏2
include::{snippets}/식별자/스니핏2.adoc[]

...

buildtask를 실행하면 (테스트 케이스가 통과한다는 가정 하에) build/generated-snippets/디렉터리에 식별자 별로 디렉터리가 생성됩니다. 식별자별로의 디렉터리엔 각각의 테스트 케이스에서 작성한 API 명세사항들이 .adoc스니핏 파일로 저장되어 있습니다.

  • .스니핏 : 스니핏의 제목을 표시하기 위해 사용합니다.
  • include::{snippets}/식별자/스니핏.adoc[] : 포함할 스니핏 문서를 가리킵니다. include::는 Asciidoctor에서 사용하는 매크로중 하나입니다.



document()

Spring Rest Docs로 API 스니핏 문서를 생성하는 것은 테스트 케이스를 사용하는 것과 동일하고 뒷부분에 추가적인 api명세만 하면 됩니다.

//when에서 mockMvc.perform()의 결과로 받았던 ResultActions//then에서
ResultActions.andExpect()메서드로 검증의 과정을 거칩니다.
검증의 과정 바로뒤에 .andDo(document()를 수행하면 API명세를 기술할 수 있습니다!

actions
	.andExpect(검증내용)
    .andDo(document(
    	"식별자",
        preprocessRequest(prettyPrint()),
        preprocessResponse(prettyPrint()),
        pathParameters(
        	parameterWithName("파라미터명").description("설명"),
            ...
        ),
        requestParameters(
        	parameterWithName("파라미터명").description("설명),
            ...
        )
        requestFields(
        	List.of(
            	fieldWithPath("경로").type(JsonFieldType.상수).description("설명"),
                ...
            )
        ),
        responseFields(
        	List.of(
            	fieldWithPath("경로").type(JsonFieldType.상수).description("설명"),
                ...
            )
        )
  • document() : API 스니핏을 만드는 메서드 입니다. 필수적으로 식별자가 포함되고 각 헨들러 메서드 마다 요구되는 매개변수가 달라집니다.
  • 식별자 : build/generated-snippets/의 하위 디렉터리로 테스트케이스별로 스니핏을 구분하는데 사용됩니다.
  • preprocessRequest(prettyPrint()) : preprocessRequest()메서드는 request의 전처리 과정에 필요한 인스턴스를 가져옵니다. prettyPrint()는 JSON으로 이루어진 내용을 읽기 쉽도록 형식화 합니다. 요청하는 값(body든 url이든)이 없다면 생략가능합니다.
  • preprocessResponse(prettyPrint()) : preprocessResponse()메서드는 response의 전처리 과정에 필요한 인스턴스를 가져옵니다. prettyPrint()는 JSON으로 이루어진 내용을 읽기 쉽도록 형식화 합니다. 응답하는 값이 없다면 생략가능합니다.
  • pathParameters() : URI에 /{변수}등 주소로 깂을 가지는 파라미터가 존재할 시 사용합니다. 사용하지 않는다면 생략 가능합니다.
  • requestParameters() : URI에 /identifier?변수1=값1&변수2=값2&...와 같이 GET방식에서 쓰는 주소에 변수와 값 쌍을 가지는 경우 사용할 수 있습니다. 사용하지 않는다면 생략 가능합니다.
  • parameterWithName("변수명").description("설명") : pathParameters()requestParameters()에서 파라미터의 갯수당 선언하여 사용합니다. 단, 요청시 파라미터는 빠짐없이 입력하여야 에러가 발생하지 않습니다.
  • requestFields(List.of()) : request body부분입니다. 보통 List로 구성되며 List안에는 requestbody의 프로퍼티들을 입력합니다.
  • responseFields(List.of()) : response body부분입니다. 보통 List로 구성되며 List안에는 responseBody의 프로퍼티들을 입력합니다.
  • fieldWithPath("속성명").type(JsonFieldType.속성).description("설명") : body에 포함된 하나의 프로퍼티를 나타냅니다. requestFields()responseFields()List.of()에서 사용되며 입력과 응답으로 구성된 모든 프로퍼티를 각각 fieldWithPath로 나타내어야 오류가 발생하지 않습니다.

API 스펙 명세는 2가지 큰 특징이 있습니다.

  1. 헨들러 메서드 마다 필요하지 않은 document()의 매개변수는 과감히 생략할 수 있습니다. 만약 GET HTTP메서드를 사용한다면 requestbody를 사용하지 않을 테니 requestFields()를 생략해도 되고, 또 파라미터를 어떻게 사용하는지에 따라 파라미터관련 매개변수들도 생략가능할 것입니다.
  2. 핸들러 메서드에서 사용된 파라미터들은 빠짐없이parameterWithName()로 구현하여야 하며 프로퍼티들은 빠짐없이 fieldWithPath()로 구현되어야 테스트 케이스를 통과합니다.

여담으로 헨들러 메서드가 아무것도 반환하지 않는다면 doNothing().when(서비스).메서드(Mockito.any타입())으로 Mock객체가 아무것도 반환하지 않도록 지정할 수도 있습니다.




후기

Spring Rest Docs를 사용하여 API명세서를 만드는 것에 대하여 학습하였습니다. SWAGGER에 비해 테스트를 통과해야 하므로 API명세를 만들기 까다롭다는 단점이 존재하지만, 컨트롤러와 모델에 애너테이션을 덕지덕지 붙히지 않아도 되고, 또 검증을 통과해야만 API문서를 만들 수 있으므로 잘못된 명세를 피할 수 있다는 장점이 존재합니다. SWAGGER와 Spring Rest Docs를 고르라면은 Mock을 활용한 테스트 검증을 못하는게 아니라면 Spring Rest Docs를 고를것 같습니다.




GitHub

private!

profile
오늘도 내일도 화이팅!

0개의 댓글