Today I Learned
(24.10.14) Swagger & Spring REST Doc
많이 사용할 수 있는 협업 상황에서의 API자동 문서화 도구 중에 Spring Framework와 관련된 툴에 관해
실제로 사용한 경험이 없기 때문에
각각의 대표적인 Swagger 와 Spring REST Doc에 관련해서 해당 툴/프레임워크에 대한 내용과 적용방법을 여럿 찾아서
정리를 했다.
관련 부분은 Postman이나 HTML로 굳이 수동으로 하나하나 적었던 개발단계에서의 API 문서가 아닌,
실제 협업을 위한 문서화에 적극적으로 활용이 되는 것 만큼
적어도 어떻게 작동이 되고 어떻게 어느 시점에 사용이 되는지를 알아둘 필요가 있어선 정리를 했다.
Swagger
- 자동으로 RESTful API 설계, 문서화, 테스트 등 관리를 할 수 있도록 하는 오픈 소스 Framework
- 자동으로 API 상세 명세 문서화
- Java Spring Boot와 함께 사용 가능
- 웹 UI를 통한 쉬운 형태의 문서를 제공
- 협업, 클라이언트와 통신에 매우 유용
- 필요한 Parameter를 빠르게 파악
- OpenAPI 기반으로 작동
- RESTful API의 기본 정의 표준 : 경로, Request 방식, Parameter, Response 형태(JSON, XML 등)
- 장점 정리
- 자동 문서화
- 최신 버전의 API 코드를 기반으로 자동으로 문서화, 문서/코드간 불일치 최소화
- API 테스트
- Swagger UI 자체에서 API 요청 테스트를 실제로 진행 가능
- 협업 용이
- 다른 협업자들에게 API 설명에 매우 용이한 도구
- 자동 문서화
구성 요소
Swagger UI
- Spring Boot에 생성된 API에 관하여 자동으로 API 문서를 웹 UI 형태로 제공하는 도구
- OAS문서를 시각적으로 표현하는 일종의 User Interface
- 경로에 접근하여, API 엔드포인트, 요청/흥답 형식 확인 및 테스트 가능
Swagger Editor
- Swagger를 통한 API 상세 명세 파일 검토 및 편집 도구
OAS, OpenAPI Specification
- 사용되고 있는 OAS 파일을 읽어 API 정의 내용을 바탕으로 API 문서를 생성
YAML 활용 방법
- OAS 기반의 API 문서를 생성하는 방법
- YAML 외 JSON 파일로도 작성이 가능
- API의 경로, 요청 방식, 요청 및 응답 파라미터 등을 정의
특징
- API 명세 / 비지니스 코드 직접 분리가 되어 있어 독립적으로 관리 가능
- 문서 직접 수정 가능
- Node, Python 등에서도 같이쓰일 수 있음 : 다른 툴과의 높은 호환성
사용방법
- YAML 파일 작성
- API에 대한 정보를 정의
// 간단한 예시 openapi: 3.0.0 info: title: Example API version: 1.0.0 description: Swagger 테스트 paths: /users: get: summary: Get all users responses: '200': description: A list of all users content: application/json: schema: type: array items: type: object properties: id: type: integer name: type: string ...
- 의존성 추가, Swagger 설정 파일 로드
- springdoc-openapi 라이브러리를 활용
- gradle에 의존성을 추가 / pom.xml에 추가
- // 의존성 추가 implementation 'org.springdoc:springdoc-openapi-ui:1.6.9'
- Spring Boot Application 내에서 1번 YAML파일을 로드할 수 있는 설정을 application.yml 에 추가
- springdoc: api-docs: path: /api-docs swagger-ui: path: /swagger-ui.html // 해당 부분은 임의로 정의 url: /v3/api-docs.yaml
- springdoc-openapi 라이브러리를 활용
- Swagger UI 접근
- http://localhost:8080/swagger-ui.html 로 접근하여 YAML 파일 기반의 API 문서확인
YAML 대표적이구조 정리
- openapi OpenAPI 명세의 버전
- info API의 기본적인 정보(title, description, version 등)
- servers API 서버의 URL과 기본 경로
- paths API 엔드포인트와 각 경로의 동작(GET, POST 등)
- components 재사용 가능한 스키마, 응답, 매개변수 등을 정의하는 섹션
- schemas 데이터 모델을 정의하여 요청과 응답에 사용할 수 있는 구조를 명시
- responses 공통적으로 사용하는 응답 객체
- parameters 경로, 쿼리, 헤더, 쿠키와 관련된 공통 매개변수
- examples 요청 및 응답의 예시 데이터
- requestBodies 요청 본문의 공통적인 정의를 명시
- headers 재사용 가능한 헤더 값
- securitySchemes 보안 체계(JWT, OAuth2 등)
- security API의 전역 보안 설정을 명시
- tags API를 그룹화하여 설명하는 태그
- externalDocs 외부 문서에 대한 링크를 제공하여 추가 정보
Spring Boot 내 구성하는 방식
- Annotation을 활용하여 API 문서를 활용
- Update 된 사항이 곧바로 반영 : 일관성을 유지
- 의존성 추가
- YAML 파일 방법과 동일
- Swagger 설정 클래스 Config 설정
- 좀더 디테일한 설정이 필요한 경우 활용 가능
- 단, 무조건이 아닌 기본경로, 보안 설정 등의 추가 적인 설정을 확장해서 사용이 가능
@Configuration @OpenAPIDefinition( info = @Info(title = "Example API", version = "1.0", description = "Swagger 테스트"), servers = @Server(url = "<http://localhost:8080>") ) public class SwaggerConfig { // 관련 설정이 있다면 }
- 좀더 디테일한 설정이 필요한 경우 활용 가능
- API 문서화 Annotation을 활용하여 코드 작성
- Controller 또는 Endpoint 부분에 Annotation과 함께 작성
// 모든 사용자를 얻는 요청에 관한 Controller @RestController @RequestMapping("/users") public class UserController { // 기타 생성자 주입 **@Operation(summary = "Get all users", description = "Returns a list of all users") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successful operation"), @ApiResponse(responseCode = "404", description = "Users not found") })** @GetMapping public ResponseEntity<CommonResponse<UsersDto>> getAllUsers() { // Service 로직을 통한 전체 사용자 목록 반환 } // Swagger 2(구버전) 표기의 예제 **@ApiOperation(value = "Get specific user") @ApiResponses(value = { @ApiResponse(code = 200, message = "Successful operation", response = String.class), @ApiResponse(code = 500, message = "Server Error") })** @PostMapping("/users/{name}") public ResponseEntity<CommonResponse<UsersDto>> getUser(@PathVariable String name) { // 특정 사람을 찾는 로직 } }
- Swagger UI 접근
- http://localhost:8080/swagger-ui.html 로 접근하여 YAML 파일 기반의 API 문서확인
Annotation 정리
- @OpenAPIDefinition OpenAPI의 전반적인 정의를 설정
- @Info API에 대한 기본 정보(제목, 설명, 버전 등)를 설정
- @Server API 서버의 URL을 설정
- @Tag API 엔드포인트를 그룹화하기 위한 태그를 정의
- @Path 항목 경로를 지정하는 어노테이션
- @Operation API의 특정 동작을 설명하고 요약(OpenAPI를 활용하는 Swagger 3에서 사용)
- @ApiOperation: 해당 메서드의 목적과 동작을 설명하는 구형(Swagger 2 에서 사용)
- @ApiResponse API 요청에 대한 응답을 설명
- @ApiResponses 여러 응답을 정의
- @Parameter API 메서드의 매개변수를 설명
- @RequestBody 요청 본문의 내용을 설명
- Controller단 메서드의 매게변수에 사용하는 것과 동일한 것, Swagge에도 자동으로 그 부분을 인지해서 자동으로 문서화 시킴
- @ApiModel 데이터 모델을 설명하기 위한 어노테이션
- @ApiModelProperty 모델의 필드를 설명
- @Schema 스키마 정의에 대한 추가 정보를 제공
Spring REST Doc
- Spring MVC와 통합되어 Spring Boot과 사용되는 RESTful 웹 서비스의 문서를 위한 도구
- API 요청/응답을 테스트 하면서 문서를 자동으로 생성하는 방식
- 특징
- 테스트 주도 문서화
- API의 요청 및 응답을 테스트하면서 문서를 자동으로 생성
- API 자체에 대한 신뢰성을 보장할 수 있음
- Markdown 문서화 가능
- Markdown 형식으로 문서를 생성 (Asciidoc 형식으로 형식이 되어있기 때문에 변환을 해야함
- Spring Framework 통합
- Spring MVC와 잘 통합되어 있으며, Spring Boot와 함께 사용하기 편리
- 커스터마이징
- 유연하게 다른 문서화 요구사항에 만족해서 충족 가능
- 테스트 주도 문서화
사용방법
- 의존성 추가
- // 테스트 코드용으로 주입하는 방식 testImplementation 'org.springframework.restdocs:spring-**restdocs**-mockmvc:2.0.6'
- MockMvc 설정
- 테스트 코드 내에서 MockMvc를 생성
@RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc @ActiveProfiles("test") public class UserControllerTest { // UserController 테스트 ㄱ **@Autowired private MockMvc mockMvc;** @Before public void setUp() { // REST Docs 설정 this.mockMvc = MockMvcBuilders .standaloneSetup(new UserController()) .apply(documentationConfiguration(this.restDocumentation)) .build(); } // 이후 관련해서 문서화 작성 }
- API 문서 생성
- @Test public void createUser() throws Exception { User user = new User("Andrew", "Kim"); **mockMvc**.perform(post("/users") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(**user**))) .andExpect(status().isCreated()) .andDo(document("create-user", requestFields( fieldWithPath("firstName").description("The user's first name"), fieldWithPath("lastName").description("The user's last name") ), responseFields( fieldWithPath("id").description("The user's ID"), fieldWithPath("firstName").description("The user's first name"), fieldWithPath("lastName").description("The user's last name") ))); }
- /users 엔드포인트 POST 요청에 대해서 문서화를 위한 작성
- 문서화 저장
- 테스트가 성공이 된다면, 문서는 build/generated-snippets 에 저장 (gradle 기준)
- 하위에 해당 문서 포맷(Markdown 외에도 HTML, Asciidoc 등)으로 파일로 저장할 수 있음
Markdown으로 저장될 수 있도록 설정하는 방법
- build.gradle 단에서 설정이 필요
plugins {
id 'org.springframework.restdocs' version '2.0.6'
id 'org.asciidoctor.convert' version '3.3.2' // Asciidoctor 플러그인 추가
}
dependencies {
asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor'
}
// Markdown으로 문서화하기 위한 설정
**asciidoctor** {
inputs.dir(file('build/generated-snippets'))
outputs.dir(file('build/docs'))
// Markdown 파일로 저장하기 위한 추가 설정
options {
backend = 'markdown' // Markdown 형식으로 출력
}
}
- Asciidoc → Markdown을 해주는 Asciidoc 플러그인을 추가를 해야함
Swagger & Spring REST Docs 비교
항목 | Swagger (OpenAPI) | Spring REST Docs |
목적과 방식 | API 문서화 및 정의 | 테스트 기반 API 문서화 |
문서 형식 | OpenAPI Specification (JSON/YAML) | Asciidoc 또는 Markdown |
UI 제공 | Swagger UI 제공 | - |
설정 방법 | YAML 파일 기반 설정 / 어노테이션 기반 설정 |
테스트 코드 기반 설정 |
주요 기능 | API 문서 자동 생성 및 시각화 | 신뢰성 있는 테스트 기반 문서 |
버전 관리 | OpenAPI 버전 관리 | 문서화된 API 버전 관리 필요 |
상태 코드 정의 | 다양한 상태 코드 및 응답 지정/정의 가능 | 실제 테스트를 기반으로 상태 코드 정의 |
API 테스트 | Swagger UI에서 직접 테스트 가능 | 별도의 테스트 코드 작성 필요 |
사용 언어 | Java, JavaScript, Python 등 다양한 언어 지원 | Java 중심 |
활용 툴 | Swagger Editor, Swagger UI, Swagger Codegen 등 | Spring Framework에서 통합 |
확장성 | 다양한 프레임워크 및 언어에 통합 가능 | Spring Framework와 강력한 통합 |
테스트 프레임워크 | - | JUnit, Mockito 등과 통합 가능 |
상세 설명 | 명세에 대한 자세한 설명 및 사용법 제공 | 테스트 기반의 명세에 대한 자세한 설명 제공 |
'Today I Learned' 카테고리의 다른 글
(24.10.21) Message Queue 그리고 Redis (1) | 2024.10.21 |
---|---|
(24.10.17) NginX 정리 + 본인 프로젝트에서 활용한 부분 추가 (1) | 2024.10.17 |
(24.10.10) TDD & DDD / Filter & Interceptor & AOP 비교해보기 (0) | 2024.10.10 |
(24.10.08) 보안 공격 정리 : SQL Injection, CSRF, XSS (0) | 2024.10.08 |
(24.10.07) CAP 이론 정리 (0) | 2024.10.07 |