plugins { 1
id "org.asciidoctor.convert" version "1.5.2"
}
dependencies { 2
testCompile 'org.springframework.restdocs:spring-restdocs-mockmvc:1.0.1.RELEASE'
}
ext { 3
snippetsDir = file('build/generated-snippets')
}
test { 4
outputs.dir snippetsDir
}
asciidoctor { 5
attributes 'snippets': snippetsDir 6
inputs.dir snippetsDir 7
dependsOn test 8
}
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 앵귤러
- 스프링 시큐리티
- 스프링 시큐리티와 앵귤러 js
- oauth2
- Spring Framework
- AUthorization
- swagger-ui
- 앵귤러JS
- spring security oauth2
- angularjs
- spring
- 스프링 세션
- 예외처리
- spring framwork
- 스웨거
- controlleradvice
- spring boot
- 스프링
- 스프링부트
- Spring Security
- Authentication
- rest api
- 스프링 부트
- Exception Handling
- 레디스
- api 문서화
- angular
- spring security and angularjs
- api documentation
- spring session
- Today
- Total
스프링부트는 사랑입니다
Spring REST Docs v1.0.1 레퍼런스 본문
스프링 REST Docs
스프링 MVC Test를 통해 자동생성된 코드와 손으로 쓰여진 문서를 합쳐서 REST 서비스를 문서화하기
소개 Introduction
스프링 REST Docs의 목표는 당신의 RESTful 서비스를 정확하고 읽기 편하게 문서화하는 것을 돕는 것이다.
높은 수준의 문서화를 하는 것은 어렵다. 이 작업에 잘 맞는 툴을 사용하는 데 있어서의 어려움을 편리하게 하는 하나의 방법의 끝으로 스프링 REST Docs는 Asciidoctor를 사용한다. 아스키닥터는 평문을 처리하여 당신의 필요에 맞는 스타일과 레이어를 적용한 HTML를 만들어준다.
스프링 REST Docs는 Spring MVC Test를 위해 쓰여진 테스트를 통해 만들어진 코드 조각들을 사용한다. 이 테스트 기반의 접근법test-driven approach은 당신의 서비스에 대한 문서화의 정확도를 보장해준다. 코드 조각이 올바르지 않다면 결과물 생성에 실패할 것이다.
하나의 RESTful서비스를 문서화하는 것은 주로 그 리소스들을 상세화하는 것이다. 각 리소스의 상세화에 두가지 주요 부분이 있는데 각각 그것이 소비하는 HTTP 요청Request의 디테일과 그 후 생성되는 HTTP 응답Response이다. 스프링 REST Docs는 당신이 이들 리소스와 HTTP요청과 응답 그리고 당신의 서비스의 구현체의 내부 디테일로 부터 문서화를 보호하는 등등의 작업할 수 있게 만들어준다. 이 분리된 방식은 당신으로 하여금 서비스의 구현체보다 당신의 서비스의 API를 문서화할수 있도록 도와준다. 또한 문서화의 재작업없이 구현체를 계속 추가/변경할 수 있다.
시작하기 Getting started
이 섹션은 스프링 REST Docs를 시작하는 법을 기술한다.
샘플 어플리케이션 Sample applications
바로 돌려볼 수 있는 두가지 샘플 어플리케이션이 있다. 하나의 샘플은 Spring HATEOAS를, 다른 하나는 Spring Data REST를 사용하였다. 둘 다 스프링 REST Docs를 사용하여 구체적인 API가이드를 만든다. 하나씩 둘러보자.
각 샘플은 API가이드를 만들어내는 api-guide.adoc
라는 이름의 파일을 하나 가지고 있으며 getting-started-guide.adoc
라는 이름의 파일은 초기에 따라할 수 있도록 시작하기 가이드를 만들어낸다.
생성된 코드조각은 src/test/java
에서 확인할 수 있다. ApiDocumentation.java
는 API가이드를 위한 코드조각을 만든다. GettingStartedDocumentation.java
는 시작하기 가이드를 위한 코드조각을 만든다.
빌드 설정 Build configuration
스프링 REST Docs를 사용하는 첫걸음은 당신의 프로젝트 빌드를 설정하는 것이다.
그래들 빌드 설정 Gradle build configuration
Spring HATEOAS 샘플은 build.gradle
파일을 포함하고 있는데 당신이 이를 레퍼런스로 사용할 수 있다. 이 설정의 주요 파트는 아래에 묘사해두었다:
1 | 아스키닥터 플러그인을 적용. |
2 | testCompile 설정에 spring-restdocs-mockmvc 의존성 추가. |
3 | 코드조각이 생성되는 결과output 폴더를 프로퍼티에 설정. |
4 | 하나의 결과물로서 코드조각 디렉토리를 추가하는 |
5 |
|
6 | 당신의 문서에 생성된 코드조각을 포함할 때 사용될 속성값인 |
7 | 입력값input으로 snippets 디렉토리 설정하기. |
8 | test task에 의존하는 task를 만들어 문서가 생성되기전에 테스트를 돌릴 수 있게함. |
문서 패키징하기 Packaging the documentation
아마도 당신은 프로젝트 jar파일안에 생성된 문서를 패키지하고 싶을 것이다. 예를 들면, 스프링 부트에 의해 정적인 컨텐트로서 제공하기 같이. asciidoctor
task 에 의존하는 jar
task 를 설정하고 jar의 정적인 디렉토리에 생성된 문서를 복사함으로서 이것이 가능하다:
jar {
dependsOn asciidoctor
from ("${asciidoctor.outputDir}/html5") {
into 'static/docs'
}
}
메이븐 빌드 설정 Maven build configuration
Spring Data REST 샘플은 pom.xml
파일을 포함하고 있어 레퍼런스로 활용이 가능할 것이다. 이 설정의 주요 파트는 아래에 묘사해두었다:
<dependency> 1
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<version>1.0.1.RELEASE</version>
<scope>test</scope>
</dependency>
<properties> 2
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
</properties>
<build>
<plugins>
<plugin> 3
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Documentation.java</include>
</includes>
</configuration>
</plugin>
<plugin> 4
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>package</phase> 6
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
<attributes>
<snippets>${snippetsDirectory}</snippets> 5
</attributes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
1 | test scope 에 spring-restdocs-mockmvc 의존성 추가하기. |
2 | 생성된 코드조각을 위한 결과 위치output location를 프로퍼티에 설정하기. |
3 | SureFire 플러그인을 추가하고 Documentation.java로 끝나는 이름을 가진 파일들을 포함하도록 설정하기. |
4 | Asciidoctor 플로그인 추가하기 |
5 | 당신의 문서에 생성된 코드조각을 포함할때 사용될 속성값인 |
6 | 프로젝트의 jar에 문서를 패키지하려면, |
문서 패키징하기 Packaging the documentation
아마도 당신을, 이를테면, 스프링 부트에 의해 정적인 컨텐트로서 제공하기와 같이 프로젝트 jar파일안에 생성된 문서를 패키지하고 싶을 것이다.
먼저 이를 위해 위에서 언급한것처럼 prepare-package
구문으로 실행하기 위해 아스키닥터 플러그인을 설정해야한다. 이제 메이븐의 리소스 플러그인을 설정하여 생성된 문서를 프로젝트의 jar의 어디에 포함시킬지 설정해보자:
<plugin> 1
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<!-- … -->
</plugin>
<plugin> 2
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
1 | 아스키닥터 플러그인을 쓰기위한 선언. |
2 | 리소스 플러그인은 아스키닥터 플러그인 이후에 선언해주어야한다. 이들은 같은 구문 (prepare-package)을 가르키는데 리소스 플러그인이 아스키닥터 플러그인 이후에 실행되어야하기 때문이다. |
문서화 조각 생성하기 Generating documentation snippets
스프링 REST Docs는 당신이 문서화하려는 서비스를 Spring’s MVC Test framework를 통해 접근한다. 그 후 요청되 결과 응답을 위한 문서 코드조각을 생성한다.
Spring MVC 테스트 설정하기 Setting up Spring MVC test
문서 코드조각을 생성하는 첫걸음은 JUnit @Rule
로 어토테이션된 public
RestDocumentation
필드를 선언하는 것이다. RestDocumentation
룰은 생성된 코드조각이 쓰여져야하는 결과 디렉토리를 설정한다. 이 결과 디렉토리output directory는 당신이 build.gradle
또는 pom.xml
파일에 설정해둔 코드조각 디렉토리snippets directory와 일치해야 한다.
메이븐에선 다음과 같다: (pom.xml
은 보통 target/generated-snippets
로 설정한다)
@Rule
public RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
그레들에선 다음과 같다: (build.gradl
, 보통 build/generated-snippets
를 사용한다)
@Rule
public RestDocumentation restDocumentation = new RestDocumentation("build/generated-snippets");
다음으로, MockMvc
인스턴스를 만드는 @Before
메소드를 제공한다:
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.build();
}
MockMvc
인스턴스는 RestDocumentationMockMvcConfigurer
를 사용하여 설정한다. 이 클래스의 인스턴스는 org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
의 documentationConfiguration()
메소드로 부터 받아온다. RestDocumentationMockMvcConfigurer
a는 민감한 기본값들을 적용하며, 또한 설정을 커스터마이징하기위한 API를 제공해준다. 더 자세한 정보는 빌드설정 섹션을 참고하자.
RESTful 서비스 호출하기 Invoking the RESTful service
이제 MockMvc
인스턴스가 생성되었으니, RESTful서비스를 호출하고 요청과 응답을 문서화하는데 사용할 수 있다. 예를 들면:
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) 1
.andExpect(status().isOk()) 2
.andDo(document("index")); 3
1 | 서비스의 루트 (/) 를 호출하고 응답이 application/json이어야 한다고 알려준다. |
2 | 서비스가 만들어내는 원하는 응답을 결정한다. |
3 | 결과 디렉토리로 설정된 위치에 |
기본값으로, 3가지 코드조각이 만들어진다:
<output-directory>/index/curl-request.adoc
<output-directory>/index/http-request.adoc
<output-directory>/index/http-response.adoc
스프링 REST Docs에 의해 만들어지는 코드조각에 대한 더 자세한 정보는 아래의 당신의 API 문서화 하기를 참고하자.
코드조각 사용하기 Using the snippets
생성된 코드조각들은 include macro를 사용하여 당신의 문서에 포함시킬 수 있다. snippets
속성은 빌드설정 섹션에서 구체적으로 알 수 있다. 예를 들면:
include::{snippets}/index/curl-request.adoc[]
당신의 API 문서화하기 Documenting your API
이 섹션에서 Spring REST Docs를 사용하여 당신의 API를 문서화하는 더 자세한 정보를 제공한다.
하이퍼미디어 Hypermedia
Spring REST Docs Hypermedia-based API의 링크들의 문서화를 지언한다.
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("index", links( 1
linkWithRel("alpha").description("Link to the alpha resource"), 2
linkWithRel("bravo").description("Link to the bravo resource")))); 3
1 | 응답의 링크를 설명하는 코드 조각을 만들어내도록 Spring REST docs를 설정하기. |
2 | rel이 |
3 | rel이 bravo인 링크를 예상함. |
결과는 리소스의 링크들을 설명하는 하나의 테이블이 들어있는 links.adoc
라는 이름의 코드조각이다.
링크들을 문서화 할 때, 응답에 문서화되지않는 링크가 발견되면 테스트는 실패할 것이다. 유사하게 옵션으로 설정되지않은 하나의 문서화된 링크가 응답에 존재하지않으면 테스트 역시 실패될 것이다.
문서화에 포함하고 싶지않은 어떤 링크가 있다면, 이를 무시하도록ignored 설정할 수 있다. 이는 위에서 설명한 테스트 실패를 피할 수 있도록 생성된 코드조각에 보여지지않을 것이다.
하이퍼미디어 링크 포멧 Hypermedia link formats
두개개의 링크 포멧이 기본값으로 사용된다:
Atom – 링크는
links
라는 이름의 배열을 예상한다. 응답의 컨텐트 타입이application/json
과 호환될때 기본값으로 사용된다.HAL – 링크는
_links
.라는 이름의 맵을 예상한다. 응답의 컨텐트 타입이application/hal+json
과 호환될때 기본값으로 사용된다.
Atom또는 HAL-포멧을 사용중이지만 다른 컨텐트 타입을 가지고 있다면 links
를 내장된 LinkExtractor
로 구현함으로서 지원가능하다. 예를 들면:
.andDo(document("index", links(halLinks(), 1
linkWithRel("alpha").description("Link to the alpha resource"),
linkWithRel("bravo").description("Link to the bravo resource"))));
1 | 링크들이 HAL 포멧이라고 알려준다. halLinks 메소드를 사용한다. |
당신의 API가 Atom 또는 HAL이외의 다른 포멧으로 링크를 나타내고 있다면, 응답에서 링크를 추출하기 위한 LinkExtractor
인터페이스를 자체 구현하여 지원할 수 있다.
요청과 응답의 페이로드 Request and response payloads
위에 언급된 이외의 추가적인 하이퍼미디어 특화된 지원을 위해, 요청과 응답 페이로드의 일반적인 문서화 지원 또한 제공된다. 예를 들어:
this.mockMvc.perform(get("/user/5").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("index", responseFields( 1
fieldWithPath("contact").description("The user's contact details"), 2
fieldWithPath("contact.email").description("The user's email address")))); 3
1 | 응답 페이로드의 필드를 설명하는 코드조각을 만드는 Spring REST docs 설정. |
2 | contact경로의 필드를 예상한다. |
3 | contact.email 경로의 필드를 예상. |
결과는 필드들이 설명된 테이블이 포함된 코드조각이다. 요청의 경우 코드조각은 request-fields.adoc
라는 이름을 가진다. 응답의 경우 코드조각은response-fields.adoc
라는 이름을 가진다.
필드를 문서화할 때, 페이로드안에 문서화되지않은 필드가 발견되면 테스트는 실패할 것이다. 이와 유사하게 문서화된 필드가 페이로드에서 발견되지않고 이 필드가 옵션으로 설정되지않았다면 테스트 역시 실패할 것이다. 계층적 구조 hierarchical structure를 가진 페이로드의 경우 하나의 필드를 문서화 하는 것으로 충분히 그의 모든 하위구조 또한 문서화 되는 것으로 간주될 수 있다.
문서화에 포함하고 싶지않은 어떤 링크가 있다면, 이를 무시하도록ignored 설정할 수 있다. 이는 위에서 설명한 테스트 실패를 피할 수 있도록 생성된 코드조각에 보여지지않을 것이다
기본값으로, Spring REST Docs 는 당신 문서화 하려는 페이로드가 JSON이라고 가정할 것이다. XML 페이로드를 문서화 하려면 요청 또는 응답의 컨텐트 타입이 |
JSON 페이로드 JSON payloads
JSON 필드 경로 JSON field paths
JSON 필드 경로는 괄호bracket나 점dot 명명법을 사용한다. 점Dot 명명법은 예를들어 a.b
와 같이 경로의 각 키를 구분하기위해 '.'을 사용한다. 괄호Bracket 명명법은 ['a']['b']
와 같이 사각괄호square brackets와 작은따옴표single quotes에 각 키를 넣는다.
[]
의 경우 배열을 나타내기 위해 사용된다. 점dot 명명법은 더 간결하지만 괄호bracket 명명법을 쓸 때 ['a.b']
와 같이 하나의 키값에 점dot을 사용할 수 있다. 같은 경로에 a['b']
와 같이 두개의 다른 명명법 사용이 가능하다.
이 JSON페이로드로:
{
"a":{
"b":[
{
"c":"one"
},
{
"c":"two"
},
{
"d":"three"
}
],
"e.dot" : "four"
}
}
다음의 경로들이 표현되었다:
Path | Value |
---|---|
| b를 포함하고 있는 하나의 객체 |
| 3개의 객체를 포함하고 있는 하나의 배열 |
| 3개의 객체를 포함하고 있는 하나의 배열 |
| 3개의 객체를 포함하고 있는 하나의 배열 |
| 3개의 객체를 포함하고 있는 하나의 배열 |
| 3개의 객체를 포함하고 있는 하나의 배열 |
| 스트링 |
| 스트링 |
| 스트링 |
|
|
루트에 배열을 사용하는 응답 또한 문서화할 수 있다. 경로 []
는 전체 배열로 참조될 것이다. 그 다음, 배열 전체에서 필드를 식별하기 위해 괄호bracket 또는 점dot 명명법을 사용할 수 있다. 예를 들면, [].id
는 다음의 배열에서 찾을 수 있는 모든 객체의 id
필드와 상응된다:
[
{
"id":1
},
{
"id":2
}
]
JSON 필드 타입 JSON field types
하나의 필드가 문서화될 때, Spring REST Docs는 페이로드를 조사함으로서 그 타입을 결정하려고 한다. 7개의 타입이 지원된다:
Type | Description |
---|---|
array | 필드의 각각 존재하는 값이 배열임 |
boolean | 필드에 각각 존재하는 값이 boolean 임 ( |
object | 필드에 각각 존재하는 값이 객체임 |
number | 필드에 각각 존재하는 값이 숫자임 |
null | 필드에 각각 존재하는 값이 null임 |
string | 필드에 각각 존재하는 값이 문자임 |
varies | 페이로드에서 서로 다은 다양한 타입을 가진 필드가 여러 번 있음 |
타입은 또한 FieldDescriptor
의 type(Object)
메소드를 사용하여 명시적으로 설정할 수 있다. Object
's toString
메소드로 결과가 문서안에 사용될 것이다. 보통 JsonFieldType
에 열거된enumerated 값들중 하나가 사용될 것이다:
.andDo(document("index", responseFields(
fieldWithPath("contact.email")
.type(JsonFieldType.STRING) 1
.optional()
.description("The user's email address"))));
1 | 필드의 타입을 |
XML 페이로드 XML payloads
XML field paths XML field paths
XML 필드 경로는 XPath를 사용하여 설명한다. /
는 자식노드로 내려가는데 사용된다.
XML 필드 타입 XML field types
XML페이로드를 문서화할 때, 반드시 FieldDescriptor
의 type(Object)
메소드를 사용하여 필드의 타입을 제공해주어야한다. 지원되는 타입의 toString
메소드의 결과값이 문서화에 사용되어질 것이다.
요청 파라미터들 Request parameters
요청 파라미터들은 requestParameters
을 사용하여 문서화할 수 있다. 요청 파라메터들은 GET
요청의 쿼리문query string안에 포함할 수 있다. 예를 들어:
this.mockMvc.perform(get("/users?page=2&per_page=100")) 1
.andExpect(status().isOk())
.andDo(document("users", requestParameters( 2
parameterWithName("page").description("The page to retrieve"), 3
parameterWithName("per_page").description("Entries per page") 4
)));
1 | 쿼리문에 page 와 per_page 두개의 파라메터를 가지는 GET 요청을 수행한다. |
2 | 요청의 파라미터를 설명하는 코드조각을 만드는 Spring REST Docs 설정. |
3 |
|
4 | per_page 파라미터를 문서화 함. |
요청 파라미터는 또한 POST 요청 바디body의 폼데이터form data를 포함시킬 수 있다.:
this.mockMvc.perform(post("/users").param("username", "Tester")) 1
.andExpect(status().isCreated())
.andDo(document("create-user", requestParameters(
parameterWithName("username").description("The user's username")
)));
1 | 단일 파라미터 |
두 경우 모두에서 결과는 리소스에 의해 지원되는 파라미터를 설명하는 테이블을 포함하는 request-parameters.adoc
이라는 이름의 코드조각이다.
요청 파라미터를 문서화할 때, 요청에서 사용되지않는 파라미터가 문서화 되어있으면 테스트는 실패할 것이다. 이와 유사하게 문서화된 요청 파라미터가 요청에서 발견되지않으면 또한 실패할 것이다.
어느 요청 파라미터를 문서화하지 않으려면 무시하도록ignored 설정함으로서 위에 묘사된 실패들을 피하도록 생성된 코드조각에 보이는 것을 방지할 것이다.
경로 파라미터들 Path parameters
요청의 경로 파라미터는 pathParameters
를 사용하여 문서화할 수 있다. 예를 들어:
this.mockMvc.perform(get("/locations/{latitude}/{longitude}", 51.5072, 0.1275)) 1
.andExpect(status().isOk())
.andDo(document("locations", pathParameters( 2
parameterWithName("latitude").description("The location's latitude"), 3
parameterWithName("longitude").description("The location's longitude") 4
)));
1 |
|
2 | 요청의 경로 파라미터를 설명하는 코드조각을 만드는 Spring REST Docs 설정. |
3 | Document the parameter named latitude 라는 이름의 파라미터를 문서화 함. org.springframework.restdocs.request.RequestDocumentation 의 정적인 parameterWithName 메소드를 사용한다. |
4 | Document the parameter named longitude 라는 이름의 파라미터를 문서화 함. |
결과는 리소스에 의해 지원되는 경로 파라미터들을 설명하는 테이블을 가진 path-parameters.adoc
라는 이름의 코드조각이다.
경로 파라미터를 문서에서 이용할 수 있게 만드려면, 요청은 |
경로 파라미터를 문서화할 때, 요청에 사용되었으나 문서화 되지않은 경로가 있으면 테스트는 실패될 것이다. 이와 유사하게, 요청에는 없는데 문서화되어있는 경로 파라미터가 있다면 또한 실패할 것이다.
어떤 경로 파라미터를 문서화에 포함하고 싶지않다면, 무시ignored하도록 설정하여 위에 언급된 실패를 회피하도록 생성되는 코드조각에 보이지 않도록 방지할 수 있다.
HTTP 헤더 HTTP headers
요청이나 응답의 헤더는 각각 requestHeaders
and responseHeaders
를 사용하여 문서화할 수 있다. 예를 들면:
this.mockMvc
.perform(get("/people").header("Authorization", "Basic dXNlcjpzZWNyZXQ=")) 1
.andExpect(status().isOk())
.andDo(document("headers", requestHeaders( 2
headerWithName("Authorization").description(
"Basic auth credentials")), 3
responseHeaders( 4
headerWithName("X-RateLimit-Limit").description(
"The total number of requests permitted per period"),
headerWithName("X-RateLimit-Remaining").description(
"Remaining requests permitted in current period"),
headerWithName("X-RateLimit-Reset").description(
"Time at which the rate limit period will reset"))));
1 | 기본 인증basic authentication에 사용되는 |
2 | 요청의 헤더를 설명하는 코드조각을 만드는 Spring REST Docs 설정. |
3 | Authorization 헤더를 문서화함 org.springframework.restdocs.headers.HeaderDocumentation의 정적인headerWithName 메소드 사용. |
4 | 응답의 헤더를 설명하는 코드조각을 만듦. |
결과는 request-headers.adoc
와 response-headers.adoc
라는 이름의 코드조각이다. 각각 헤더를 설명하는 테이블을 가지고 있다.
HTTP헤더를 문서화할 때, 문서화된 헤더를 요청이나 응답에서 찾을 수 없다면 테스트는 실패할 것이다.
제약사항 문서화하기 Documenting constraints
Spring REST Docs 는 문서의 제약사항을 도와주는 많은 클래스들을 제공한다. ConstraintDescriptions
의 인스턴스는 클래스의 제약사항에 대한 설명에 접근하는데 쓴다. 예를 들어:
public void example() {
ConstraintDescriptions userConstraints = new ConstraintDescriptions(UserInput.class); 1
List<String> descriptions = userConstraints.descriptionsForProperty("name"); 2
}
static class UserInput {
@NotNull
@Size(min = 1)
String name;
@NotNull
@Size(min = 8)
String password;
}
1 | UserInput 클래스를 위한 ConstraintDescriptions 인스턴스를 만든다 |
2 | Get이름 프로퍼티의 제약사항의 설명을 가져옴. 이 리스트는 두개의 설명을 가지고 있는데; 하나는 |
Spring HATEOAS 샘플에서 ApiDocumentation
클래스는 이 함수가 어떻게 동작하는 지 보여준다.
제약사항 찾기 Finding constraints
기본값으로 제약사항들은 Bean Validation을 사용하여 찾는다. 현재는 오직 프로퍼티 제약사항만 지원한다. 당신은 커스텀 ValidatorConstraintResolver
인스턴스로 ConstraintDescriptions
를 만드는 데 사용되는 Validator
를 커스터마이즈할 수 있다. 제약사항을 완전히 제어하려면, 사용하는 ConstraintResolver
를 스스로 구현하면 된다.
제약사항 기술하기 Describing constraints
기본 설명값들descriptions은 Bean Validation 1.1의 제약사항에서 지원하는 전체 리스트는 다음과 같다:
AssertFalse
AssertTrue
DecimalMax
DecimalMin
Digits
Future
Max
Min
NotNull
Null
Past
Pattern
Size
기본 설명값들descriptions을 오버라이드 하거나 새로운 설명을 제공하려면 org.springframework.restdocs.constraints.ConstraintDescriptions
. 의 기본이름을 가지는 리소스 번들을 만들어야한다. Spring HATEOAS-based 샘플은 이러한 리소스 번들 예제를 포함하고 있다.
리소스 번들의 각각의 키는 제약사항의 완전한 이름의 뒤에 .description
을 더한 것이다. 예를 들어, 표준의 @NotNull
제약사항의 키는 javax.validation.constraints.NotNull.description
이다.
프로퍼티 placeholder은 제약사항의 설명description에서 사용된 속성값을 참조한다. 예를 들어, @Min
제약사항의 기본 설명default descripton인 Must be at least ${value}는 제약사항의 value
속성을 참조한다.
제약사항 설명의 더 많은 제어를 위해서 커스텀 ResourceBundleConstraintDescriptionResolver
를 가지고 ConstraintDescriptions
를 만들어야 한다. 완전한 제어를 하러면, 커스텀 ConstraintDescriptionResolver
구현으로 ConstraintDescriptions
를 만들어야 한다.
생성된 코드조각에서 제약사항 기술하기 Using constraint descriptions in generated snippets
일단 제약사항의 설명을 가지고 있다면, 이들을 마음놓고 사용할 수 있다. 하지만 당신은 생성된 코드조각을 선호할 것이다. 예를 들어, 제약사항 설명을 필드의 설명의 일부로서 포함시키길 원할 수 있다. 또는 요청 필드 코드조각의 추가 정보로서 제약사항을 포함할 수 있다. Spring HATEOAS-based 샘플의 ApiDocumentation
클래스에서 후자의 접근법을 확인할 수 있다.
기본 코드조각들 Default snippets
당신이 MockMvc.perform
을 호출하여 문서화 할 때 수많은 코드조각들이 자동으로 만들어진다:
Snippet | Description |
---|---|
| 문서화를 위한 |
| 문서화를 위한 |
| 리턴되는 HTTP응답을 포함한다. |
당신은 어떤 코드조각을 기본값으로 만들지 설정할 수 있다. 자세한 정보는 설정 섹션을 보자.
파라메터화된 결과 디렉토리 사용하기 Using parameterized output directories
document
에 의해 사용되는 결과 디렉토리는 파라미터화할 수 있다. 다음의 파라미터들이 지원된다:
Parameter | Description |
---|---|
{methodName} | 테스트 메소드의 변경이 불가능한 이름 |
{method-name} | kebab-case를 사용하여 포멧된, 테스트 메소드의 이름 |
{method_name} | snake_case를 사용해 포멧된 테스트 메소드의 이름 |
{ClassName} | 테스트 클래스의 변경이 불가능한 이름 |
{class-name} | kebab-case를 사용하여 포멧된 테스트 클래스의 이름 |
{class_name} | snake_case를 사용하여 포맷된 테스트 클래스의 이름 |
{step} | 현재 테스트의 MockMvc.perform를 호출한 수 |
예를 들어, 테스트 클래스 GettingStartedDocumentation
의 creatingANote
라는 이름의 테스트 메소드의 document("{class-name}/{method-name}")
는 getting-started-documentation/creating-a-note
.라는 이름의 디렉토리에 코드조각을 만들것이다.
파라미터화된 결과 디렉토리는 특히 스프링 MVC 테스트의 alwaysDo
기능과 같이 쓸 때 매우 유용하다. 이는 설정 메소드안에 문서화의 설정을 가능하게 해준다:
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.alwaysDo(document("{method-name}/{step}/"))
.build();
}
여기 설정된 값으로 MockMvc.perform
으로의 모든 호출은 더 많은 설정없이도 default snippets을 만들어낼 것이다. 이 함수가 어떻게 동작하는지 보려면 각각 샘플 어플리케이션에 있는 GettingStartedDocumentation
클래스를 보자.
결과값 커스터마이징하기 Customizing the output
생성된 코드조작 커스터마이징하기 Customizing the generated snippets
Spring REST Docs는 Mustache 템플릿을 사용하여 생성된 코드조작을 만든다. 기본 템플릿은 스프링 REST Docs가 만들어내는 각각의 코드조각를 제공한다. 코드조각의 내용을 커스터마이즈하기위해 당신 자신만의 템플릿을 사용할 수 있다.
템플릿들은 org.springframework.restdocs.templates
패키지의 클래스 패스로부터 불러와지며 각각의 템플릿은 코드조각후에 이름이 지어지고 만들어낼 것이다. 예를 들어, curl-request.adoc
코드조각을 위한 템플릿을 오버라이드 하려면 src/test/resources/org/springframework/restdocs/templates
에 curl-request.snippet
이라는 이름의 템플릿을 만들어야한다.
추가정보 포함하기 Including extra information
생성된 코드조각을 포함할 때 추가 정보는 제공하는 두가지 방법이 있다:
하나 이상의 속성의 설명자descriptor에
attributes
메소드를 사용한다.curlRequest
,httpRequest
,httpResponse
등등을 호출할 때 몇가지 속성값을 넘긴다. 이러한 속성값들은 전체 코드조각에 할당될 것이다.
추가적인 속성값을 템플릿이 처리되는 과정에서 이용할 수 있다. 커스텀 코드조각 템플릿들을 함께 엮어서 생성된 코드조각에 추가정보는 넣는것이 가능해진다.
위의 설명의 간단한 예로 요청 필드를 문서화할 때 제약사항 컬럼과 타이틀을 추가해보자. 이를 위한 첫번째 스텝은 당신이 문서화하려는 각각의 필드에 constraints
속성을 제공하고 title
속성을 제공하는 것이다:
A concrete example of the above is the addition of a constraints column and a title when documenting request fields. The first step is to provide a constraints
attribute for each field that you are documenting and to provide a title
attribute:
.andDo(document("create-user", requestFields(
attributes(
key("title").value("Fields for user creation")), 1
fieldWithPath("name")
.description("The user's name")
.attributes(
key("constraints").value("Must not be null. Must not be empty")), 2
fieldWithPath("email")
.description("The user's email address")
.attributes(
key("constraints").value("Must be a valid email address"))))); 3
1 | 요청 필드의 코드조각을 위한 title 속성을 설정 |
2 | name 필드를 위한 constraints 속성을 설정 |
3 |
|
두번째 절차는 생성된 코드조각의 테이블의 필드 제약사항와 타이틀을 추가하기 위한 정보를 포함하는 request-fields.snippet
이름의 커스텀 템플릿을 제공해주는 것이다:
.{{title}} 1
|===
|Path|Type|Description|Constraints 2
{{#fields}}
|{{path}}
|{{type}}
|{{description}}
|{{constraints}} 3
{{/fields}}
|===
1 | 테이블에 title 추가하기 |
2 | "Constraints" 이라는 이름의 새 컬럼 추가 |
3 | 테이블의 각 열에 설명자descriptor의 |
요청과 응답 커스터마이징하기 Customizing requests and responses
당신이 정확히 보낸 어떠한 요청과, 어떠한 받은 요청을 문서화 하고 싶지않는 상황이 있을 수 있다. Spring REST Docs는 많은 선행처리자들preprocessors을 제공하여 요청과 응답을 문서화하기 전 단계에서 변경할 수 있다.
선행처리Preprocessing는 OperationRequestPreprocessor
와/또는OperationResponsePreprocessor
를 가진 document
을 호출함으로서 설정할 수 있다. 인스턴스들은 Preprocessors
의 정적인 preprocessRequest
와 preprocessResponse
를 사용함으로서 받아올 수 있다. 예를 들어:
this.mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andDo(document("index",
preprocessRequest(removeHeaders("Foo")), 1
preprocessResponse(prettyPrint()))); 2
1 | Foo 라는 이름의 헤더를 지우는 요청 선행처리자를 적용함. |
2 | 응답의 내용을 이쁘게 출력pretty print하게 하는 응답 선행처리자를 적용함. |
다른 방법으로, @Before
메소드의 선행처리자를 설정하고 파라미터화한 출력 디렉토리 지원을 사용함으로서, 모든 테스트에 똑같은 선행처리자를 적용할 수 있다.
@Before
public void setup() {
this.document = document("{method-name}", 1
preprocessRequest(removeHeaders("Foo")),
preprocessResponse(prettyPrint()));
this.mockMvc = MockMvcBuilders
.webAppContextSetup(this.context)
.alwaysDo(this.document) 2
.build();
}
1 | 요청과 응답 선생처리를 위한 설정하는 RestDocumentationResultHandler 만들기. |
2 | 문서화 결과 처리자result handler를 항상 호출하도록 설정하는 |
그 후 각각의 테스트에서 RestDocumentationResultHandler
는 어떠한 특정 목적의 테스트를 위한 설정을 할 수 있다. 예를들어:
this.document.snippets( 1
links(linkWithRel("self").description("Canonical self link")));
this.mockMvc.perform(get("/")) 2
.andExpect(status().isOk());
1 | 테스트되는 리소스를 구체화한 링크를 문서화함. Document the links specific to the resource that is being tested |
2 | 위에 사용된 alwaysDo의 사용때문에 |
위에 언급된 것을 포함한 다양한 내장 선행처리자들이 Preprocessors
의 정적 메소드를 통해 이용할 수 있다. 더 자세한 내용은 아래를 보라.
선행처리자들 Preprocessors
이쁘게 출력하기 Pretty printing
Preprocessors
의 prettyPrint
는 요청과 응답의 내용을 더 읽기 쉽게 만들어준다.
링크 마스킹하기 Masking links
하이퍼미디어 기반의 API를 문서화하려는 중이라면, 클라이언트들이 하드코드된 URI를 사용하기보다는 링크를 사용하여 API를 찾아가기를 권할 것이다. 이를 위한 하나의 방법은 문서의 URI의 사용을 제한하는 것이다. Preprocessors
의 maskLinks
는 응답에 포함된 모든 href
링크들을 …
. 로 변경해준다. 이것은 당신이 원하는 다른 내용으로도 변경할 수 있다.
헤더 지우기 Removing headers
Preprocessors
의 removeHeaders
는 요청과 응답에 있는 특정한 헤더 이름을 지운다.
패턴 변경하기 Replacing patterns
은 요청과 응답의 내용을 바꾸는 일반적인 목적의 메카니즘을 제공한다. 정규식을 통해 나오는 모든 내욜이 변경될 것이다. Preprocessors
의 replacePattern
자신만의 선행처리자 작성하기 Writing your own preprocessor
만일 내장 선행처리자들이 당신의 필요를 채울 수 없다면, OperationPreprocessor
인터페이스를 구현함으로서 자신만의 것을 만들수 있다. 그 후 당신의 커스텀 선행처리자를 아무 내장된 선행처리자와 똑같은 방식으로 사용하면 된다.
만일 요청이나 응답의 내용(body)만 변경하고자 하면, ContentModifier
인터페이스를 구현하고 이를 내장 ContentModifyingOperationPreprocessor
와 함께 사용하는 것을 고려해보자.
설정 Configuration
문서화된 URI들 Documented URIs
스프링 REST Docs의 URI 문서화를 위한 기본 설정값들은 다음과 같다:
Setting | Default |
---|---|
Scheme |
|
Host |
|
Port |
|
이 설정은 RestDocumentationMockMvcConfigurer
에 의해 적용된다. 당신은 이 API를 당신이 필요로 하는 하나 또는 그 이상의 기본값들을 바꾸는 데 쓸 수 있다:
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).uris()
.withScheme("https")
.withHost("example.com")
.withPort(443))
.build();
요청의 컨텍스트 경로를 설정하려면, |
코드조각 인코딩 Snippet encoding
아스키닥터가 사용하는 기본 인코딩은 UTF-8
이다. Spring REST Docs 는 코드조각을 만드는데 똑같은 값을 사용한다. 만일 UTF-8
이 아닌 다른 인코딩을 사용하려면 RestDocumentationMockMvcConfigure
를 통해 설정하자:
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).snippets()
.withEncoding("ISO-8859-1"))
.build();
기본 코드조각들 Default snippets
3가지 코드조각들이 기본적으로 만들어진다:
curl-request
http-request
http-response
이 기본 설정은 RestDocumentationMockMvcConfigurer
에 의해 적용된다. 당신은 이 API를 설정을 바꾸는데 쓸 수 있다 . 예를 들어, 기본적으로 curl-request
코드조각만을 만드려면:
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).snippets()
.withDefaults(curlRequest()))
.build();
아스키닥터 작동하기 Working with Asciidoctor
이 섹션은 Spring REST Docs와 연관된 아스키닥터와 함께 동작하는 관점들에 대해 설명하였다.
리소스 Resources
코드조작 포함하기 Including snippets
include macro 는 당신의 문서에 생성된 코드조각을 포함사는데 사용된다. snippets
속성은 빌드 설정에서 구체적으로 다루었는데 코드조각의 출력 디렉토리를 참조하는데 사용된다. 예를 들어:
include::{snippets}/index/curl-request.adoc[]
태블릿 커스터마이징하기 Customizing tables
많은 코드조각들이 기본 설정에 의한 테이블을 포함하고 있다. 테이블의 모양은 코드조각이 포함될때 추가적인 설정을 제공하거나, 커스텀 코드조각 템플릿을 사용함으로서 커스터마이즈할 수 있다.
컬럼 포멧팅 Formatting columns
아스키닥터는 테이블의 컬럼 포멧팅을 위한 많은 다양한 지원을 하고 있다. 예를 들어, 테이블 컬럼의 폭은 cols
속성을 사용하여 특정할 수 있다:
[cols=1,3] 1
include::{snippets}/index/links.adoc[]
1 | 두개의 컬럼으로 분리되는 테이블의 폭은 두번째 컬럼이 첫번째 컬럼보다 3배 더 크다. |
테이블의 타이틀은 .
접두어를 사용한 줄에 의해 특정지을 수 있다:
.Links 1
include::{snippets}/index/links.adoc[]
1 | 테이블의 타이틀은 |
더 읽을 거리 Further reading
테이블을 커스터마이징하는 더 자세한 정보는 아스키닥터 사용자 메뉴얼의 테이블 섹션을 참고하자.
'API Documentation' 카테고리의 다른 글
Spring REST API에 Swagger 2 설정하기 (1) | 2016.03.05 |
---|---|
스웨거(Swagger) 2.0으로 스프링 부트 REST API 문서화하기 (0) | 2016.03.04 |