spring restdoc 을 만들어 보자
restdoc을 쓸수도 있을 거 같아서 정리 한다. spring-boot 기준으로 작성 하였다.
기본적인 spring-boot를 안다고 가정하고 작성한다.
...
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
....
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Documentation.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.2.1</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
<attributes>
<snippets>${project.build.directory}/generated-snippets</snippets>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<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>
...
restdocs-mockmvc 디펜더시랑 plugin 을 추가하자.
필자의 파일 경로로 하지 않아도 된다.
필자는
generated-snippets 에 snippets 설정 했다.
여기에 실제 adoc 파일들이 추가된다.
그리고 테스트 케이스를 만들어야 된다.
테스트 케이스는 기존에 필자가 포스팅 한거랑 비슷한대 약간 추가 되는 부분이 있다. 살펴보자
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringTestApplication.class)
@WebAppConfiguration
@FixMethodOrder(MethodSorters.JVM)
public class AccountControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Rule
public RestDocumentation restDocumentation =
new RestDocumentation("target/generated-snippets");
@Before
public void before() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext)
.apply(documentationConfiguration(this.restDocumentation))
// .alwaysDo(document("{method-name}/{step}/"))
.alwaysDo(document("{class-name}/{method-name}/"))
.build();
}
@Test
public void getAccounts() throws Exception {
this.mockMvc.perform(get("/accounts").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.[0].name", is("wonwoo")));
}
@Test
public void getAccount() throws Exception {
this.mockMvc.perform(get("/account/{id}", 1).accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", is("wonwoo")));
}
@Test
public void createAccount() throws Exception {
Account account = new Account();
account.setName("wonwoo123");
this.mockMvc.perform(post("/account").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(account)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.name",is("wonwoo123")));
}
}
나머진 일반 테스트 케이스처럼 작성하면 되고
before
부분만 변경 되었다.
before의 alwaysDo 메소드에 있는 class-name과 method-name은 위에서 말했던 generated-snippets/* 폴더 아래에 classname/methodname/
형식으로 추가된다.
작성 후에 테스트를 실행 하여 보자. 만약 성공 되었다면 target/generated-snippets/ 아래 폴더에 파일들이 생성 되어있는걸 볼 수 있다.
그리고 나서 src/main/asciidoc/index.adoc 를 추가하자. (필자 기준)
= RESTful Notes API Guide
Andy Wilkinson;
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 4
:sectlinks:
[[overview]]
= Overview
[[overview-http-verbs]]
== HTTP verbs
RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
use of HTTP verbs.
|===
| Verb | Usage
| `GET`
| Used to retrieve a resource
| `POST`
| Used to create a new resource
| `PATCH`
| Used to update an existing resource, including partial updates
| `DELETE`
| Used to delete an existing resource
|===
[[overview-http-status-codes]]
== HTTP status codes
RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
use of HTTP status codes.
|===
| Status code | Usage
| `200 OK`
| The request completed successfully
| `201 Created`
| A new resource has been created successfully. The resources URI is available from the responses
`Location` header
| `204 No Content`
| An update to an existing resource has been applied successfully
| `400 Bad Request`
| The request was malformed. The response body will include an error providing further information
| `404 Not Found`
| The requested resource did not exist
|===
== 사용자 리스트 조회 [get]
사용자를조회
include::{snippets}/account-controller-test/get-accounts/curl-request.adoc[]
=== 요청 구조
==== 요청 파라미터들
include::{snippets}/account-controller-test/get-accounts/http-request.adoc[]
=== 응답 구조
==== 응답 파라미터들
include::{snippets}/account-controller-test/get-accounts/http-response.adoc[]
== 사용자 조회 [get]
사용자를조회
include::{snippets}/account-controller-test/get-account/curl-request.adoc[]
=== 요청 구조
==== 요청 파라미터들
include::{snippets}/account-controller-test/get-account/http-request.adoc[]
=== 응답 구조
==== 응답 파라미터들
include::{snippets}/account-controller-test/get-account/http-response.adoc[]
== 사용자 입력 [post]
사용자를조회
include::{snippets}/account-controller-test/create-account/curl-request.adoc[]
=== 요청 구조
==== 요청 파라미터들
include::{snippets}/account-controller-test/create-account/http-request.adoc[]
=== 응답 구조
==== 응답 파라미터들
include::{snippets}/account-controller-test/create-account/http-response.adoc[]
윗 부분은 spring에서 퍼온거라.. asciidoc이라는 문법이다.
asciidoc-syntax-quick-reference 문법은 여기서 참고.
== 사용자 리스트 조회 [get]
이 부분 부터가 필자가 만들었다. 이쁘진 않지만..
나머지는 그냥 다 문법이고 추가 해야 되는 부분이 있는데
include
하는 이 부분이다.
위에서 말했던 파일들을 include 하는 부분이다. 저기에 각각의 페이지가 include 된다.
실제 파일들이 어떻게 생겼는지 보자.
curl이 작성 되어있다. 파일명은 curl-request.adoc로 떨궈진다.
[source,bash]
----
$ curl http://localhost:8080/accounts -i -H Accept: application/json
----
다음으로 reqeust 정보이다. 실제 rest api 의 method, resource, message 정보들이 적혀있다. (물론 지금은 메시지가 없어서)
[source,http]
----
GET /accounts HTTP/1.1
Accept: application/json
Host: localhost
----
마지막으로 response 정보이다. 실제 서버에서 내려 받은 정보를 보여준다.
[source,http]
----
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 81
[ {
"id" : 1,
"name" : "wonwoo"
}, {
"id" : 2,
"name" : "kevin"
} ]
----
메이븐 기준으로 되어있으니 메이븐을 실행해보자.
mvn install
그러면 target/generated-docs 아래 index.html 파일이 생성 되어 있을 것이다.
한번 열어 보자! 그럼 깔끔한 api 문서가 만들어져있다.
잘 실행되었다면 위와 같은 화면을 볼 수 있을 것이다.