inblog logo
|
jay0628
    SpringBoot

    [Spring Boot] 74. 스프링부트 블로그 v3 (RestAPI) (19) Spring REST Docs API 문서 자동화

    김주희's avatar
    김주희
    May 15, 2025
    [Spring Boot] 74. 스프링부트 블로그 v3 (RestAPI) (19) Spring REST Docs API 문서 자동화
    읽어보기

    1. build.gralde 의존성 추가

    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
    notion image
     

    2. build.gradle 플러그인 추가

    notion image
     

    3. build.gradle 플러그인 추가

    ext { snippetsDir = file('build/generated-snippets') } test { useJUnitPlatform() outputs.dir snippetsDir systemProperty 'file.encoding', 'UTF-8' } asciidoctor { inputs.dir snippetsDir dependsOn test outputDir = file("${buildDir}/docs/asciidoc") } task copyDocs(type: Copy) { dependsOn asciidoctor from("${asciidoctor.outputDir}") into("src/main/resources/static/docs") } bootJar { dependsOn copyDocs }
     
    'buildDir' is deprecated 문제 -> outputDir = layout.buildDirectory.dir("docs/asciidoc").get().asFile
     

    ext { set('snippetsDir', file("build/generated-snippets")) } tasks.named('test') { outputs.dir snippetsDir useJUnitPlatform() } tasks.named('asciidoctor') { inputs.dir snippetsDir dependsOn test } bootJar { dependsOn asciidoctor copy { // src/docs/asciidoc == from 경로 from "${asciidoctor.outputDir}" into 'src/main/resources/static/docs' // /static/docs로 복사! } }
    수정 전
    notion image
     
    수정 후
    notion image
    notion image
     

    4. MyRestDoc 클래스 생성

    notion image
    notion image
    수동설정 한 이유 .apply~ 를 쓰려고 하는거 → generated-snippets가 만들어ㅣㅈ도록 하려고
    @AutoConfigureRestDocs 이게 있으면 알아서 해줌
     
    .alwaysDo(document) → actions.andDo(MockMvcResultHandlers.print()).andDo(document); 안해도 됨
     

    이제부터는 추상클래스 상속받을거야
    notion image
    실제 서버 실행시 진짜 주소 http → https, localhost → ? 8080 → ? 로 수정해야 된다.
    @AutoConfigureRestDocs(uriScheme = "http", uriHost = "localhost", uriPort = 8080)
     
     
    notion image
    notion image
     
    actions.andDo(MockMvcResultHandlers.print()).andDo(document);
    notion image
    notion image
     
     
    어느 폴더에 할지 = build.gradle에서 한것
     
    notion image
     
    build하면 return된느 결과 값들을 redirection해서 generated 폴더 안에 모아 그걸 가지고 문서가 만들어짐
     
     

    BoardControllerTest도 수정해보자!

    1. 추가하기
      1. extends MyRestDoc
    1. 추가하기
      1. @AutoConfigureRestDocs(uriScheme = "http", uriHost = "localhost", uriPort = 8080)
    1. 삭제하기
      1. @Autowired private MockMvc mvc;
    1. 메서드마다 추가하기
      1. actions.andDo(MockMvcResultHandlers.print()).andDo(document);
     

    .adoc 파일 하나를 만들어줘야 여기로 모인다.
    notion image
     
    api.adoc에 추가
    asciidoc이 이걸 보고 html을 만들어줌
    ifndef::snippets[] :snippets: ./build/generated-snippets endif::[] :user: user-controller-test :post: post-controller-test = REST API :toc: left :toclevels: 2 :source-highlighter: highlightjs == 회원 === 1. 회원가입 ===== Request Example include::{snippets}/{user}/save_테스트/http-request.adoc[] ===== Response Example include::{snippets}/{user}/save_테스트/http-response.adoc[] ===== Curl include::{snippets}/{user}/save_테스트/curl-request.adoc[] === 2. 회원정보 ===== Request Example include::{snippets}/{user}/find_한건_테스트/http-request.adoc[] ===== Response Example include::{snippets}/{user}/find_한건_테스트/http-response.adoc[] === 3. 회원목록 ===== Request Example include::{snippets}/{user}/find_전체_테스트/http-request.adoc[] ===== Response Example include::{snippets}/{user}/find_전체_테스트/http-response.adoc[] == 게시글 === 1. 게시글등록 ===== Request Example include::{snippets}/{post}/save_테스트/http-request.adoc[] ===== Response Example include::{snippets}/{post}/save_테스트/http-response.adoc[] ===== Curl include::{snippets}/{post}/save_테스트/curl-request.adoc[] === 2. 게시글상세보기 ===== Request Example include::{snippets}/{post}/find_한건_테스트/http-request.adoc[] ===== Response Example include::{snippets}/{post}/find_한건_테스트/http-response.adoc[] === 3. 게시글목록보기 ===== Request Example include::{snippets}/{post}/find_전체_테스트/http-request.adoc[] ===== Response Example include::{snippets}/{post}/find_전체_테스트/http-response.adoc[]
    → 수정하기
     
    notion image
    ifndef::snippets[] :snippets: ./build/generated-snippets endif::[] :user: user-controller-test :board: board-controller-test :reply: reply-controller-test :love: love-controller-test = REST API :toc: left :toclevels: 2 :source-highlighter: highlightjs == 회원 === 1. 회원가입 유저네임 중복 실패 ===== Request Example include::{snippets}/{user}/join_username_uk_fail_test/http-request.adoc[] ===== Response Example include::{snippets}/{user}/join_username_uk_fail_test/http-response.adoc[] ===== Curl include::{snippets}/{user}/join_username_uk_fail_test/curl-request.adoc[] === 2. 회원가입 ===== Request Example include::{snippets}/{user}/join_test/http-request.adoc[] ===== Response Example include::{snippets}/{user}/join_test/http-response.adoc[] ===== Curl include::{snippets}/{user}/join_test/curl-request.adoc[] === 3. 로그인 ===== Request Example include::{snippets}/{user}/login_test/http-request.adoc[] ===== Response Example include::{snippets}/{user}/login_test/http-response.adoc[] ===== Curl include::{snippets}/{user}/login_test/curl-request.adoc[] === 4. 회원정보수정 ===== Request Example include::{snippets}/{user}/update_test/http-request.adoc[] ===== Response Example include::{snippets}/{user}/update_test/http-response.adoc[] ===== Curl include::{snippets}/{user}/update_test/curl-request.adoc[] === 4. 회원정보수정 ===== Request Example include::{snippets}/{user}/update_test/http-request.adoc[] ===== Response Example include::{snippets}/{user}/update_test/http-response.adoc[] ===== Curl include::{snippets}/{user}/update_test/curl-request.adoc[] === 5. 유저네임중복확인 ===== Request Example include::{snippets}/{user}/check_username_available_test/http-request.adoc[] ===== Response Example include::{snippets}/{user}/check_username_available_test/http-response.adoc[] ===== Curl include::{snippets}/{user}/check_username_available_test/curl-request.adoc[] == 게시글 === 1. 게시글등록 ===== Request Example include::{snippets}/{board}/list_test/http-request.adoc[] ===== Response Example include::{snippets}/{board}/list_test/http-response.adoc[] ===== Curl include::{snippets}/{board}/list_test/curl-request.adoc[]
     
    // 직접 mvc를 설정하면 필터를 직접 설정해줘야 한다. Autowired는 설정만해도 동작함
     

    가짜환경에 필터가 담겨야하는데 수동설정하면 안담겼던 것
    @AutoConfigureRestDocs → mvc 설정해줌
    package shop.mtcoding.blog; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.restdocs.operation.preprocess.Preprocessors; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; @AutoConfigureRestDocs(uriScheme = "http", uriHost = "localhost", uriPort = 8080) @AutoConfigureMockMvc // MockMvc 클래스가 IoC로드 @ExtendWith({SpringExtension.class, RestDocumentationExtension.class}) public abstract class MyRestDoc { @Autowired protected MockMvc mvc; protected RestDocumentationResultHandler document; @BeforeEach public void documentSetUp() { this.document = MockMvcRestDocumentation.document("{class-name}/{method-name}", Preprocessors.preprocessRequest(Preprocessors.prettyPrint()), Preprocessors.preprocessResponse(Preprocessors.prettyPrint())); } }
     
     

    ./gradlew clean build 서버 실행 http://localhost:8080/docs/api.html (src/main/resources/static 폴더 자동 인식하니까)
    notion image
     

     
     
    notion image
    // 3. 문서만들기 // 1. gradlew build (test코드 실행 -> 결과 build/generated-snippets 에 copy한다. *.adoc) - 변수 설정 완료 ext { set('snippetsDir', file("build/generated-snippets")) } // 2. gradlew build (test코드 실행 -> 진짜로 1번의 결과가 실횅됨) tasks.named('test') { outputs.dir snippetsDir useJUnitPlatform() } // 3. 테스트가 종료되면 asciidoctor 실행 -> *.adoc 파일들을 가지고 하나의 .adoc 파일로 변경 (src/docs/asciidoc) tasks.named('asciidoctor') { inputs.dir snippetsDir dependsOn test } // 4. HTML 파일을 서버에서 열어볼 수 있게 Copy tasks.register('copyRestDocs', Copy) { dependsOn tasks.named('asciidoctor') from "${asciidoctor.outputDir}" // asciidoctor 결과 위치 into "src/main/resources/static/docs" } tasks.named('bootJar') { dependsOn tasks.named('copyRestDocs') }
     
    swagger
    단점
    *가독성 낮고
    *신뢰성 낮고
     
    rest docs
    통합테스트 코드 - > 단점이자 장점
    이걸 통해서 문서가 나올 수 있고 신뢰성 있는
     
    notion image
    notion image
    Share article

    jay0628

    RSS·Powered by Inblog