HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
♥️
2기 최종 프로젝트 팀별 공간
/
팀 02 : 머쓱한녀석들
팀 02 : 머쓱한녀석들
/
🎏
BackEnd
/
🕋
기술문서
/
👓
Swaager에 대해
👓

Swaager에 대해

날짜
Jul 19, 2022
담당자
태그
swaager
완료여부
완료
실행 환경 Spring Rest Docs Gradle 설정적용장점 단점 Swaager 알아보기 전에 알아야 할 개념 Swaager 종류 뭘 써야할까? Swagger 적용 의존성 추가 application.yml 파일 설정 Config 클래스 추가 Authorization Header는? 작성 Request, Response 객체 설정 장점 단점 RestDocs + Swagger-UI우리들의 선택은? Reference

실행 환경

  • java : 11
  • gradle : 7.4.1
 

Spring Rest Docs

  • 먼저 전 프로젝트에서 사용했던 Rest Docs를 보겠습니다.
 

Gradle 설정

plugins { id 'org.springframework.boot' version '2.7.1' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'org.asciidoctor.jvm.convert' version '3.3.2'. // (1) id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { asciidoctorExtensions // (2) } repositories { mavenCentral() } ext { set('snippetsDir', file("build/generated-snippets")) // (3) } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' // (4) testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' // (5) } tasks.named('test') { outputs.dir snippetsDir useJUnitPlatform() } tasks.named('asciidoctor') { // (6) configurations 'asciidoctorExtensions' sources{ include("**/index.adoc") } baseDirFollowsSourceFile() inputs.dir snippetsDir dependsOn test } asciidoctor.doFirst { //(7) delete file('src/main/resources/static/docs') } task createDocument(type: Copy) { // (8) dependsOn asciidoctor from file("build/docs/asciidoc") into file("src/main/resources/static") } bootJar { // (9) dependsOn createDocument }
  • (1) : gradle 7버전부터는 org.asciidoctor.jvm.convert 을 사용해야 합니다.
  • (2) : asciidoctorExtensions 을 설정해줍니다.
  • (4), (5) : asciidoctorExtensions 과 docs 생성을 위한 spring-restdocs-mockmvc 의존성을 추가해줍니다.
  • (6) : dependsOn으로 test task가 실행된 이후 실행되는 task입니다.
    • sources에 명시한 adoc만 html로 변환하게 해줍니다.
    • baseDirFollowsSourceFile의 경우 docs/asciidoctor/domain과 같이 폴더 구조로 adoc을 만들었을 때 index.adoc에서 include했을 경우 path를 찾지 못하기 때문에 설정해줘야 합니다.
  • (7) : 문서 최신화를 위해 앞전에 만들었던 docs파일을 삭제합니다. doFirst로 인해 asciidoctor가 실행되기 전에 실행하게 됩니다.
  • (8) : 완성된 html을 static 폴더에 넣어 서버를 띄우게 되면 볼 수 있도록 합니다.
  • (9) : bootJar가 실행되기 전에 createDocument task를 실행하게 됩니다.
    • 이를 통해 build시에 docs파일이 jar파일에 들어갈 수 있습니다.
 

적용

@RestController public class TestController { @GetMapping("/users") public ResponseEntity<TestResponse> get() { return ResponseEntity.ok(new TestResponse("test")); }
@SpringBootTest @AutoConfigureMockMvc @AutoConfigureRestDocs class TestControllerTest { @Autowired private MockMvc mockMvc; @Autowired private ObjectMapper objectMapper; @DisplayName("레스트 독스 테스트") @Test void TestControllerTest() throws Exception { // given // when mockMvc.perform(get("/users") .contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpectAll( status().isOk(), jsonPath("name").value("test") ) // then .andDo(document("test", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), responseFields( fieldWithPath("name").type(JsonFieldType.STRING).description("테스트") ))); } }
  • 테스트를 통해 스니펫을 생성해줍니다.
  • adoc 파일을 생성합니다 (src/docs/asciidoc)
ifndef::snippets[] :snippets: ../../../build/generated-snippets endif::[] :doctype: book :icons: font :source-highlighter: highlightjs :toc: left :toclevels: 3 :sectlinks: :docinfo: shared-head == 예약 게스트 API === 예약 생성 ==== Request ===== Request HTTP Example include::{snippets}/test/http-request.adoc[] ==== Response include::{snippets}/test/response-fields.adoc[] ===== Response HTTP Example include::{snippets}/test/http-response.adoc[]
 
 
 
  • 이후 빌드를 해보면 자동적으로 html 파일이 src/main/resources/static으로 들어가게 됩니다.
 
notion image
 
  • 이후 서버를 실행하게 되면 아래와 같이 docs파일이 생성됩니다.
notion image
 
 

장점

  • 테스트 기반으로 동작하기 때문에 프로덕션 코드에는 영향이 없습니다.
    • 테스트 코드가 강제되므로 문서의 신뢰성이 높습니다.
  • 문서가 매우 직관적입니다.
 

단점

  • 엔드 포인트마다 수많은 코드를 작성해야합니다.
  • 테스트가 없다면 프론트에게 넘겨줄 문서가 없습니다.
  • Swagger와는 다르게 테스트를 즉석으로 할 수 없습니다.
 

Swaager

 

알아보기 전에 알아야 할 개념

  • Open API : 개방된 API라는 뜻으로 누구나 사용될 수 있도록 API의 endpoint가 개방되어 있습니다.
  • OpenAPI : RESTful API를 기 정의된 규칙에 맞게 API spec을 json이나 yaml로 표현하는 방식을 의미합니다.
    • 직접 소스코드나 문서를 보지 않고 서비스를 이해할 수 있다는 장점이 있습니다.
    • RESTful API 디자인에 대한 정의 표준이라고 생각하면 됩니다.
  • Swaager는 OpenAPI를 구현하기 위한 도구입니다.
 

Swaager 종류

notion image
notion image
Springfox Swaager
  • 2018년까지 Springfox Swaager는 많은 사용자들이 사용했지만 2018년 6월을 마지막으로 업데이트가 중단되었습니다. ( 2년만에 업데이트가 되긴 했습니다. )
 
Springdoc
notion image
notion image
  • Springfox Swaager의 업데이트가 중단한 사이 Springadoc이 나오게 되었습니다.
  • Springfox보다 좀 더 쉽게 사용할 수 있게 만들었다고 합니다.
 

뭘 써야할까?

notion image
  • Springdoc이 꾸준하게 업데이트를 하고 있다는 점에서 springadoc를 사용하는 것이 좋을 것 같습니다.
  • Swaager-ui를 포함하는 형태로 가지고 있습니다.

Swagger 적용

의존성 추가

implementation 'org.springdoc:springdoc-openapi-ui:1.6.9'
 

application.yml 파일 설정

springdoc: version: '@project.version@' swagger-ui: path: /api-docs operations-sorter: method tags-sorter: alpha api-docs: path: /api-docs/json
  • api-docs.path
    • 기본값 : /v3/api-docs
    • api를 OpenAPI3을 이용하여 json 형식화 한 것의 경로
  • sorter : method : 메서드순 , alpha: 알파벳 오름차순
  • swagger-ui.path
    • 기본값 : swagger-ui.html
  • 이외에도 여러 값 지정가능
[Swagger] Open API 3.0 그리고 Swagger v3
※ 실습 프로젝트는 Github 에서 확인 할 수 있습니다. API에 대한 정보를 전달하기 위해 일일이 문서화하는 것은 매우 번거로운 작업이다. 매번 Rest API를 개발하고 수정하면서 API문서를 변경하는 것은 개발자의 생산성 또한 떨어뜨린다. Swagger는 이러한 API문서를 자동으로 생성하여 HTML로 만들어주는 오픈 소스 프레임워크이다. Open API Specification의 약자로 RESTful API 를 기술하는 표준이다.
[Swagger] Open API 3.0 그리고 Swagger v3
https://jeonyoungho.github.io/posts/Open-API-3.0-Swagger-v3/
[Swagger] Open API 3.0 그리고 Swagger v3
 

Config 클래스 추가

package com.example.demo; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; @Configuration public class OpenApiConfig { @Bean public OpenAPI openAPI(@Value("${springdoc.version}") String appVersion) { Info info = new Info() .title("만두만두만두만두") .version(appVersion) .description("이것은 만두 API입니다."); return new OpenAPI() .components(new Components()) .info(info); } }
notion image
notion image
 

Authorization Header는?

@Configuration class OpenApiConfig { @Bean fun customOpenAPI(): OpenAPI? { return OpenAPI().components( Components().addSecuritySchemes( "bearer-key", SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT") ) ) } }
 

작성

@Tag(name = "유저", description = "유저 관련 API입니다.") @RestController public class TestController { @Operation(summary = "유저 다건 조회", description = "유저 단건 조회 API입니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공", content = @Content(schema = @Schema(implementation = TestResponse.class))), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(schema = @Schema(implementation = TestResponse.class))) }) @GetMapping("/users") public ResponseEntity<TestResponse> get() { return ResponseEntity.ok(new TestResponse("test")); } @Operation(summary = "유저 가입", description = "유저 가입 API입니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공", content = @Content(schema = @Schema(implementation = TestResponse.class))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = TestResponse.class))) }) @PostMapping("/users") public ResponseEntity<TestResponse> post( @RequestBody TestRequest testRequest ) { TestResponse response = new TestResponse("1"); URI location = ServletUriComponentsBuilder.fromCurrentRequest() .path("{id}") .buildAndExpand(response.getName()) .toUri(); return ResponseEntity.created(location) .body(response); } }
  • @Tag
    • api 그룹 설정을 위한 어노테이션
    • name이 같은 것끼리 하나의 api그룹으로 묶게 됩니다.
  • @Operation
    • api 상세 정보 설정을 위한 어노테이션
    • summary, description, responses, parameters 속성 등 추가 가능
  • @ApiResponses
    • 여러개의 @ApiResponse를 묶기 위한 어노테이션
  • @ApiResponse
    • api의 response 설정을 위한 어노테이션
    • responseCode, description, implementation( responsebody로 제공될 클래스 타입만 설정 가능 )
  • @Parameter
    • api parameter 설정을 위한 어노테이션
    • name, description, in( 파라미터 위치)
notion image
notion image
notion image
 

Request, Response 객체 설정

public class TestRequest { @Schema(description = "이름", defaultValue = "testName") private String name; } public class TestResponse { @Schema(description = "반환 이름", defaultValue = "testName") private String name; }
  • @Schema
    • Request, Resposne 객체에 대한 설정을 위한 어노테이션
    • description, defaultValue, example
notion image
 
 
이외에도 세세히 설정할 수 있습니다.
 

장점

  • API문서에서 API테스트를 즉시 해볼 수 있습니다.
  • 문서가 이쁩니다.
 

단점

  • 테스트 코드 없이도 생성할 수 있어서, API 문서를 신뢰하기 어렵습니다.
  • 프로덕션 코드에 영향이 있습니다.
 

RestDocs + Swagger-UI

  • Swagger는 프로덕션 코드에 덕지덕지 붙고 Swagger 코드를 작성해야 한다는 단점이 있고 Rest Docs는 문서 작성을 위한 코드가 테스트 코드에 있기 때문에 테스크 코드가 강제되며 문서를 통해 테스트가 불가능하다.
  • 두 개의 장점만 가진 방법은 없을까?
restdocs-api-spec
ePages-de • Updated Aug 18, 2022
 
 

우리들의 선택은?

 
 
 

Reference

Spring Rest Docs와 Swagger 조합하기
API 문서 자동화를 도와주는 Spring Rest Docs와 Swagger 을 조합해, 단점은 버리고 장점만 누려봅시다 가장 많이 사용되는 API 문서를 자동화 해주는 프레임워크로 Swagger와 Spring Rest Docs 두개가 있다. 이 포스팅에서는 필자가 생각하는 두 프레임워크의 장단점과 이로 인해 느끼는 불편, 그리고 이를 어떻게 극복했는지에 대해 기록 할 것이다.
Spring Rest Docs와 Swagger 조합하기
https://shirohoo.github.io/backend/test/2021-07-17-swagger-rest-docs/
Spring Rest Docs와 Swagger 조합하기
Swagger와 Spring Restdocs의 우아한 조합 (by OpenAPI Spec)
MSA 환경에서의 API 문서화는 어떤 식으로 구성하는 걸까? 예컨대, 모듈이 10개 있다고 하면 각 모듈마다 API 문서가 만들어질 테고 API 문서를 클라이언트에 제공하기 위해서 각각의 (10개의) URL를 전달해야 할 텐데 이게 과연 효율적일까? 물론 기능별로 URL이 분리된다는 장점이 있고 굳이 모아보자면 각 API 문서를 다시 한번 크롤링 하여 검색할 수 있도록 제공하는 것도 하나의 방법이 될 수 있다.
Swagger와 Spring Restdocs의 우아한 조합 (by OpenAPI Spec)
https://taetaetae.github.io/posts/a-combination-of-swagger-and-spring-restdocs/
Swagger와 Spring Restdocs의 우아한 조합 (by OpenAPI Spec)
Spring Rest Docs와 Open Api (Swagger)
안녕하세요! 오늘은 Spring 진영의 문서화 프레임워크인 Spring Rest Docs와 Swagger를 비교하는 글을 작성해 볼까 합니다. Peloton 프로젝트 진행 중에 문서화와 관련해서 고민했던 부분들을 정리 해보았어요. 함께 공유해보면 좋을 것 같아요. Spring Rest Docs로 작성된 문서 Spring Rest docs는 Test 기반으로 동작합니다. 테스트 코드에 추가함으로써 문서가 작성돼요. 따라서 Production 코드에 영향을 미치지 않는다는게 큰 장점입니다.
Spring Rest Docs와 Open Api (Swagger)
https://velog.io/@bread_dd/Spring-Rest-Docs%EC%99%80-Open-Api-Swagger
Spring Rest Docs와 Open Api (Swagger)
OpenAPI 란? (feat. Swagger)
Overview 이 문서에서는 API의 기본적인 정의는 알고 있다는 전제하에 OpenAPI와 Swagger의 개념, 차이점, 비교적 최근(2017-07-26) 업데이트한 OpenAPI 3.0에 대해서 알아보도록 하겠습니다. 1. OpenAPI? Open API? 검색창에 OpenAPI라고 치면 수많은 결과가 나옵니다. 근데 의미가 통일되지 않고 중구난방인데요... 그래서 더 헷갈립니다. 저도 이게 대체 무슨 뜻인가 싶었습니다. 그래서 정리하는 정확한 정의!
https://gruuuuu.github.io/programming/openapi/
OpenAPI 란? (feat. Swagger)
Swagger. Springfox-Swagger 그리고 Springdoc
요즘 스프링으로 프로젝트를 하면서 이런저런 지식들을 습득하고 있습니다. 예전에 스프링으로 프로젝트하시던 분들이 swagger를 이용해서 API문서를 만들던 것을 보고 swagger라는 것에 대해 듣게 되었었는데요. 다만 개념을 제대로 이해하고 있지 못했었습니다. springfox-swagger라고 적힌 걸 보고 그냥 같은 녀석이라고 생각을 했었는데요. 알고 보니 springfox-swagger와 swagger랑은 다른 녀석이었습니다. 물론 관련은 있지만요. Swagger는 2011년에 처음 릴리즈 되었습니다.
Swagger. Springfox-Swagger 그리고 Springdoc
https://junho85.pe.kr/1583
Swagger. Springfox-Swagger 그리고 Springdoc
[Swagger] Open API 3.0 그리고 Swagger v3
※ 실습 프로젝트는 Github 에서 확인 할 수 있습니다. API에 대한 정보를 전달하기 위해 일일이 문서화하는 것은 매우 번거로운 작업이다. 매번 Rest API를 개발하고 수정하면서 API문서를 변경하는 것은 개발자의 생산성 또한 떨어뜨린다. Swagger는 이러한 API문서를 자동으로 생성하여 HTML로 만들어주는 오픈 소스 프레임워크이다. Open API Specification의 약자로 RESTful API 를 기술하는 표준이다.
[Swagger] Open API 3.0 그리고 Swagger v3
https://jeonyoungho.github.io/posts/Open-API-3.0-Swagger-v3/
[Swagger] Open API 3.0 그리고 Swagger v3