Spring REST Docs
클라이언트 입장에선 어떤 API 가 있는지 모르므로 문서화가 필요하다.
개발자가 코드 수정하고 문서도 같이 수정 안하면 쌓이고 쌓여서 결국 코드기능과 문서 스펙이 일치하지 않을수있다
[Spring Rest Docs 장점]
- 운영코드에 영향이없다. (애노테이션이나 XML 같은게 없다)
- 변경시에도 Test 케이스 실행 후 문서를 최신화가 해서 생성해준다.
설정방법이 그리 어렵지는 않고 순서대로 설명해주니 스프링 공식 문서를 참고하자.
build.gradle
본인 기준 설정을 마친 build.gradle 파일은 아래와 같으며 설정을 마쳤으면 코끼리를 돌리면 된다.
build.gradle 의 맨 아랫줄만 조금 다르고 나머진 다 같으니 맨 아래 부분만 이걸 참고하면 된다.
너무 길어서 접어놓았으니 필요 시 열어 보자.
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.15'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
// 플러그인 추가
id "org.asciidoctor.jvm.convert" version "3.3.2"
}
group = 'com.dunple'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '11'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
// asciidoc 설정
asciidoctorExt
}
repositories {
mavenCentral()
}
ext {
// 버전 관리용으로 상수로 뺀다
asciidocVersion = "2.0.7.RELEASE"
// test 를 통해 생성되는 asciiDoc 경로 지정
snippetsDir = file('build/generated-snippets')
}
dependencies {
// SpringBoot
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
// RestDocs
asciidoctorExt "org.springframework.restdocs:spring-restdocs-asciidoctor:${asciidocVersion}"
testImplementation "org.springframework.restdocs:spring-restdocs-mockmvc:${asciidocVersion}"
// QueryDsl
implementation "com.querydsl:querydsl-core"
implementation "com.querydsl:querydsl-jpa"
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" // querydsl JPAAnnotationProcessor 사용 지정
annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError(javax.annotation.Entity) 발생 대응
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// H2
runtimeOnly 'com.h2database:h2'
// test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
// 대충 경로지정한단 뜻
test {
outputs.dir snippetsDir
}
// 대충 테스트 진행하고 문서 생성한다는 뜻
asciidoctor {
inputs.dir snippetsDir
configurations 'asciidoctorExt'
dependsOn test
}
// 대충 최종적으로 jar 파일 생성할때 asciidoc 도 같이 생성될 수 있게 한다는뜻
bootJar {
dependsOn asciidoctor
copy{
from asciidoctor.outputDir
into 'src/main/resources/static/docs'
}
}
PostControllerDocTest
전에 @SpringBootTest 에서는 MockMvc 빈 주입이 안된다고 했었다.
여기서는 우리가 전에 했던 방식인 @AutoConfigureMockMvc 를 써서 의존성 주입을 받은게 아니라
아래처럼 @BeforeEach 에서 RestDoc 에 필요한 설정으로 MockMvc 를 직접 초기화 시켰다.
이제 기존에 하던것 처럼 테스트를 작성하면 asciidoc 이 생성된다. 단건 조회 테스트를 예시로 작성해보자.
@SpringBootTest
@ExtendWith(RestDocumentationExtension.class)
public class PostControllerDocTest {
private MockMvc mockMvc;
@Autowired
private PostRepository postRepository;
@BeforeEach
void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation))
.build();
}
@DisplayName("글 단건 조회 테스트")
@Test
void test1() throws Exception {
// given
Post post = Post.builder()
.title("우리 이쁜 미카공주님")
.content("우리 공주님")
.build();
postRepository.save(post);
this.mockMvc.perform(
MockMvcRequestBuilders.get("/posts/{postId}", 1L)
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isOk())
.andDo(print())
.andDo(document("index"));
}
}
테스트를 수행하면 위 사진처럼 generated-snippets 폴더에 asciidoc 파일들이 생성됨을 확인할 수 있다.
테스트 맨 아랫줄에 작성한 .andDo(document("폴더이름")) 으로 폴더 이름을 설정할 수 있다.
해당 폴더 안에 HTTP 요청 및 응답 정보, 요청 및 응답의 body 정보가 asciidoc 으로 생성된다.
그런 다음 아래처럼 src 폴더 아래에 src.docs.asciidoc 폴더를 만들고 asciidoc 폴더 안에 (폴더이름).adoc 파일을 만든다.
여기서는 index.adoc 으로 만들겠다.
index.adoc
그리고 그 adoc 파일에 아래와 같은 양식으로 위에서 생성했던 asciidoc 중 원하는 걸로 설정한다.
인텔리제이에서 이쁘게 보라고 플러그인 설치하라고 하는데 설치하면 오른쪽에서 미리보기를 볼 수 있다.
마크다운 문법과 비슷하다.
= 미카 공주님 API
:toc:
== 글 단건 조회
=== 요청
include::{snippets}/index/http-request.adoc[]
=== 응답
include::{snippets}/index/http-response.adoc[]
=== CURL
include::{snippets}/index/curl-request.adoc[]
ㄴ :toc:
적용하면 아래처럼 목차를 표현할 수 있다.
'API 만들어 보기 > 게시판 API' 카테고리의 다른 글
[API 인증] Interceptor 사용해보기 (0) | 2023.09.29 |
---|---|
[API 인증] 가장 기본적인 요청 인증값 확인 (0) | 2023.09.28 |
[예외처리] 예외처리 2 (0) | 2023.09.26 |
[예외처리] 예외처리 1 (0) | 2023.09.26 |
[게시글 삭제] 게시글 삭제 (0) | 2023.09.26 |