가자공부하러!

Spring REST Docs(1) - 기초 환경설정 본문

공부/Spring Boot

Spring REST Docs(1) - 기초 환경설정

오피스엑소더스 2019. 12. 24. 08:29

참고 : https://docs.spring.io/spring-restdocs/docs/2.0.2.RELEASE/reference/html5/

참고 : https://cheese10yun.github.io/spring-rest-docs/

참고 : http://wonwoo.ml/index.php/post/476

참고 : https://seungwoo0429.tistory.com/34

참고 : https://jojoldu.tistory.com/299

참고 : https://spring.io/projects/spring-restdocs

 

개발환경

Spring Boot 2.2.2(maven)

JDK 1.8

* 주의 : gradle과 maven은 몇몇 세부내용들이 다름(패키지 경로 등)

* 주의 : Spring Boot 버전과 restdocs-mockmvc버전을 맞추게 되는데, 버전에 따라 설정이 달라진다

 - SpringBoot 2.2.2에서는 @AutoConfigureMockMvc, @AutoConfigureRestDocs...(본문 맨 아래 3.문제해결 참고)

 - SpringBoot 1.2.2에서는 아래처럼..

//Spring Boot 1.2.2에서의 테스트 클래스
public class RestDocsTest {

  @Autowired
  private WebApplicationContext context;

  @Rule
  public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");

  @Before
  public void setUp() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
        .apply(documentationConfiguration(this.restDocumentation)).build();
  }

  @Test
  public void connChk() throws Exception{
    mockMvc ...;
  }
}
//Spring Boot 2.2.2에서의 테스트 클래스
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureRestDocs
@Import(RestDocsConfiguration.class)
public class MarketTest {

  @Autowired
  private MockMvc mockMvc;

  @Autowired
  private ObjectMapper objectMapper;
  
  ...
  
 }

1. Spring REST Docs?

1.1. 개요

 - Asciidoctor로 직접 작성한 문서와 Spring MVC 테스트를 통해 자동 생성된 스니펫을 결합해서 웹 문서를 만든다.

 - Spring MVC 테스트를 활용해서 API문서의 조각을 생성해주는 라이브러리

  > 문서조각 : snippet으로 지칭

  > 가능 테스트 : MockMVC, WebTestClient(Spring 5.* 이상), REST Assured, JUnit5, TestNG 등

  > 작성한 테스트 자체가 API 문서로 활용되는 느낌

 - 기본적인 산출물은 html문서이고 Markdown을 사용하도록 설정할 수 있다.

1.2. 장점과 단점

 - 장점

  > API 스펙이 변경되어도 문서를 수정할 필요 없음

  > 테스트를 하지 않은 내용이 있는 경우 문서화를 하도록 강제할 수 있음

 - 단점

  > 만들기 꽤 귀찮음

1.3. 흐름과 구조

 - 흐름 :

  > REST Docs 환경설정(테스트케이스 작성 등)

  -> maven clean

  -> html파일을 생성해줄 index.adoc파일 생성(asciidoc디렉토리)

  -> 테스트 케이스 수행

  -> 테스트 결과가 adoc파일로 생성됨(snippets)

  -> index.adoc에서 테스트 결과를 모아 문서 틀 작성(snippet import 등)

  -> maven install(안되면 package) -> target/generated-docs 경로에 index.html 확인

  -> app run

 - 구조 :

  > TestCase를 수행하면 테스트의 산출물이 <document-name>.adoc파일로 /build/generated-snippets 디렉토리에 생성됨(default-path)

  > /src/asciidoc 디렉토리에 /build/generate-snippets에 있는 adoc파일을 include하여 문서를 생성할 수 있음

   - /build/generate-snippets/*.adoc : 명세들만 있는 파일(API Request, Response 등에 대한)

   - /src/asciidoc/*.adoc  : 실제 사용자들에게 html 파일로 변환되어 제공되는 API 문서 파일

프로젝트 구조와 생성된 문서

 

 

2. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hjmin</groupId>
    <artifactId>jpaboard</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>jpaboard</name>
    <description>JPA Board Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-mockmvc</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.asciidoctor</groupId>
                <artifactId>asciidoctor-maven-plugin</artifactId>
                <version>1.5.3</version>
                <executions>
                    <execution>
                        <id>generate-docs</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>process-asciidoc</goal>
                        </goals>
                        <configuration>
                            <backend>html</backend>
                            <doctype>book</doctype>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.springframework.restdocs</groupId>
                        <artifactId>spring-restdocs-asciidoctor</artifactId>
                        <version>2.0.2.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <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>
        </plugins>
    </build>
</project>

 

 

3. 오류 해결

3.1. http://localhost:18081/docs/api-guide.html 에서 include한 내용들이 잘못 보이는 경우

api-guide.adoc(좌), 의도와 다르게 출력된 api-guide.html(우)

 - 추정원인 : {snippets} 경로가 잘못된 듯

 - 해결 : 테스트클래스에 설정 변경

  > 기존 : @Rule... @Before...

  > 변경 : 

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureRestDocs
@Import(RestDocsConfiguration.class)
public class CommonControllerTest { 
	...
}

 

 

 

Comments