반응형
해당 글에서는 Spring Boot 3.x 버전 내에서 Swagger3을 SpringDoc OpenAPI Starter WebMVC UI를 통해 이해하고 설정하는 방법에 대해 알아봅니다.
💡 [참고] Swagger에 대해 상세히 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
분류 | 링크 |
RESTful API 설계 방법 -1 : 이해하기 | https://adjh54.tistory.com/150 |
RESTful API 설계 방법 -2 : 구성하기 | https://adjh54.tistory.com/151 |
Spring Boot 2.x 환경에서 Swagger 이해하고 적용하기 : SpringDoc openAPI UI | https://adjh54.tistory.com/72 |
Spring Boot 3.x 환경에서 Swagger3 이해하고 적용하기-1 : SpringDoc OpenAPI Starter WebMVC UI 및 구성 방법 | https://adjh54.tistory.com/561 |
Spring Boot 3.x 환경에서 Swagger3 이해하고 적용하기 -2 : @RequestParam, @PathVariable, @RequestBody, @RequestHeader 정의 방법 | https://adjh54.tistory.com/618 |
Spring Boot 환경에서 Swagger 예제 Repository | https://github.com/adjh54ir/blog-codes/tree/main/spring-boot-swagger |
1) Swagger
💡Swagger
- RESTful 웹 서비스를 설계, 구축, 문서화 및 사용할 수 있는 오픈 소스 소프트웨어 프레임워크를 의미합니다.
- 이를 통해 API의 구조와 동작을 정의하기 위한 도구와 사양 세트를 제공하여 API를 개발하고 유지하는 것을 더욱 쉽게 만들어줍니다. API의 엔드포인트, 매개변수, 응답 등을 정의하고 문서화할 수 있습니다.
- 어노테이션을 기반으로 작동하고 사용이 되며 API의 구조와 동작에 대해 정의를 합니다. 또한 Swagger를 이용하기 위해서는 라이브러리인 SpringFox나 SpringDoc OpenAPI를 사용해야 합니다.
- Rest API에서 설계 과정 중 'API 문서화 단계'에서 이를 사용합니다.
1. Swagger 2
💡Swagger 2
- RESTful API를 설계, 빌드, 문서화 및 사용하기 위한 오픈 소스 소프트웨어 프레임워크입니다.
특징 | 설명 |
JSON 또는 YAML 형식 | API 설명을 JSON 또는 YAML 형식으로 작성할 수 있습니다. |
기본 데이터 타입 | 문자열, 숫자, 부울 등의 기본 데이터 타입을 지원합니다. |
경로 매개변수 | URL 경로에 포함된 매개변수를 정의할 수 있습니다. |
요청 및 응답 스키마 | API 요청 및 응답의 구조를 정의할 수 있습니다. |
보안 정의 | API 인증 및 권한 부여 방식을 설명할 수 있습니다. |
2. Swagger 3(OpenAPI 3) : OAS(OpenAPI Specification)
💡 Swagger2의 개선된 버전으로, OpenAPI Specification(OAS) 3.0을 기반으로 합니다.
특징 | 설명 |
컴포넌트 재사용 | 스키마, 응답, 매개변수 등을 재사용 가능한 컴포넌트로 정의할 수 있습니다. |
향상된 보안 스키마 | OAuth2, OpenID Connect 등 다양한 인증 방식을 더 자세히 설명할 수 있습니다. |
콜백 지원 | 웹훅과 같은 비동기 작업을 설명할 수 있습니다. |
링크 객체 | API 응답 간의 관계를 정의할 수 있어 HATEOAS를 더 잘 지원합니다. |
서버 변수 | 여러 서버 환경을 쉽게 정의하고 전환할 수 있습니다. |
요청 본문 개선 | 여러 콘텐츠 타입을 지원하고, 요청 본문을 더 유연하게 정의할 수 있습니다. |
3. Swagger 3 개선사항
💡 Swagger2에서 Swagger3을 사용하게 됨에 따라서 개선된 사항에 대해서 알아봅니다.
개선 사항 | 설명 |
더 나은 구조화 | 컴포넌트를 통해 API 정의를 더 모듈화하고 재사용할 수 있습니다. |
확장성 향상 | 새로운 기능과 사용 사례를 더 잘 지원합니다. |
더 상세한 보안 정의 | 다양한 인증 방식을 더 자세히 설명할 수 있습니다. |
비동기 API 지원 | 콜백을 통해 비동기 작업을 더 잘 설명할 수 있습니다. |
더 유연한 스키마 | 복잡한 데이터 구조를 더 쉽게 표현할 수 있습니다. |
[ 더 알아보기 ]
💡 그러면 무슨 라이브러리가 Swagger2, Swagger3가 되는가?
- Spring Boot 2.x 버전까지는 Springfox나 SpringDoc OpenAPI UI를 사용하여 Swagger2 또는 초기 Swagger3(OpenAPI 3.0)를 구현했습니다.
- Spring Boot 3.x 버전부터는 SpringDoc OpenAPI Starter WebMVC UI를 사용하여 Swagger3(OpenAPI 3.0)를 구현합니다.
2) Swagger UI 경로에 접속 이후 404 에러 발생
💡Swagger UI 경로에 접속 이후 404 에러 발생
- 기존의 Spring Boot 2.x 환경에서 사용하고 있었던 SpringDoc OpenAPI 라이브러리에서 Spring Boot 3.x 버전으로 마이그레이션을 했을 때, Swagger-ui에 접속하는 경우 404 에러가 발생하였습니다.
💡[참고] Spring Boot 2.x 버전에서 사용하였던 SpringDoc OpenAPI UI 라이브러리
1. 문제점 확인
💡 문제점 확인
- 기존에 접속이 잘 되던 Swagger-ui를 Spring Boot 3.x 버전으로 마이그레이션 함에 따라서 경로를 찾지 못하는 오류(404)가 발생함을 확인하였습니다.
💡공식사이트에 접속
- 아래와 같이 springdoc-openapi v1.8.0 최신 버전의 경우 공식 사이트에서 아래와 같이 이야기하고 있습니다.
💡springdoc-openapi v1.8.0 is the latest Open Source release supporting Spring Boot 2.x and 1.x. An extended support for springdoc-openapi v1 project is now available for organizations that need support beyond 2023. For more details, feel free to reach out: sales@springdoc.org
- springdoc-openapi v1.8.0의 경우 Boot 2.x 및 1.x를 지원하는 최신 오픈 소스 릴리스입니다. 2023년 이후에도 지원이 필요한 조직을 위해 springdoc-openapi v1 프로젝트에 대한 확장 지원이 이제 제공됩니다. 자세한 내용은 sales@springdoc.org로 문의하세요.
2. 해결 방법
💡해결 방법
- 아래와 같이 springdoc-openapi-starter-webmvc-ui 라이브러리를 사용하기를 권장하고 있습니다.
dependencies {
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0" // Swagger UI
}
3) Swagger 라이브러리 종류 및 비교
💡Swagger 라이브러리 종류 및 비교
- Spring, Spring Boot 환경에서 적용이 되었던 Swagger 라이브러리의 종류들을 확인하고, 각각 적용이 가능한 버전들에 대해서 알아봅니다.
라이브러리 | 특징 | Spring Boot 호환성 | OpenAPI 버전 |
SpringFox Swagger2 | - Spring 기반 애플리케이션용 - 자동 Swagger 2.0 문서 생성 - 최근 업데이트 중단 |
Spring Boot 2.x까지 | Swagger2 |
SpringDoc OpenAPI UI | - Spring Boot 애플리케이션용 - 자동 OpenAPI 3 문서 생성 - 활발한 유지보수 |
Spring Boot 1.x, 2.x | Swagger3 |
SpringDoc OpenAPI Starter WebMVC UI | - Spring Boot 3.x용 - WebMVC 애플리케이션 지원 - Swagger UI 통합 |
Spring Boot 3.x | Swagger3 |
[ 더 알아보기]
💡 Swagger와 Swagger 라이브러리의 차이점은 무엇일까?
- Swagger: API 설계, 문서화, 테스트를 위한 오픈소스 프레임워크 및 사양을 의미합니다.
- Swagger 라이브러리: Swagger 사양을 구현하고 애플리케이션에 통합하기 위한 도구를 의미합니다.
- 즉, Swagger는 개념과 사양을 정의하고, Swagger 라이브러리는 이를 실제로 구현하여 개발자가 쉽게 사용할 수 있게 해주는 도구입니다.
1. SpringFox Swagger2
💡SpringFox Swagger2
- Spring 기반 애플리케이션에서 Swagger 2.0 문서를 자동으로 생성하기 위한 라이브러리를 의미합니다.
- SpringFox Swagger2는 최근 업데이트가 2020년 이후 중단되어 Spring Boot 3.x 버전과 호환성 문제가 있을 수 있습니다. 따라서 최신 프로젝트에서는 SpringDoc OpenAPI를 사용하는 것이 권장됩니다.
https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
2. SpringDoc OpenAPI UI
💡SpringDoc OpenAPI UI
- Spring Boot 애플리케이션에서 OpenAPI 3 (이전의 Swagger) 문서를 자동으로 생성하기 위한 라이브러리입니다.
- 해당 라이브러리의 경우 Spring Boot 2.x 및 1.x에 대해서 지원하는 라이브러리입니다. 즉, 최신 Spring Boot 3.x 버전을 사용하는 경우 지원을 하지 않습니다.
https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui
3. SpringDoc OpenAPI Starter WebMVC UI
💡 SpringDoc OpenAPI Starter WebMVC UI
- Spring Boot 3.x 버전과 호환되는 OpenAPI (Swagger) 문서 생성 라이브러리입니다.
- Spring Boot 3.x에서 WebMVC 애플리케이션을 위한 OpenAPI 3 (Swagger) 지원을 제공합니다.
- 자동으로 API 문서를 생성하고 Swagger UI를 통해 시각화합니다.
https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui
4) SpringDoc OpenAPI Starter WebMVC UI 주요 어노테이션
1. 어노테이션 종류
어노테이션 | 설명 | 사용위치 |
@OpenAPIDefinition | API 문서의 전체적인 정보를 정의합니다. 제목, 설명, 버전 등을 설정할 수 있습니다. | 클래스 레벨 |
@Tag | API 그룹을 정의합니다. 컨트롤러나 메서드에 태그를 지정하여 API를 분류할 수 있습니다. | 클래스 또는 메서드 레벨 |
@Operation | API 엔드포인트에 대한 상세 정보를 제공합니다. 요약, 설명, 응답 등을 설정할 수 있습니다. | 메서드 레벨 |
@Parameter | API 메서드의 파라미터에 대한 설명을 추가합니다. | 메서드 파라미터 레벨 |
@RequestBody | 요청 본문에 대한 설명을 추가합니다. | 메서드 파라미터 레벨 |
@ApiResponse | API 응답에 대한 설명을 추가합니다. 상태 코드, 설명, 응답 스키마 등을 정의할 수 있습니다. | 메서드 레벨 |
@Schema | 모델 클래스나 필드에 대한 스키마 정보를 정의합니다. | 클래스 또는 필드 레벨 |
@Hidden | 특정 API 엔드포인트나 모델을 문서에서 숨깁니다. | 클래스, 메서드, 또는 필드 레벨 |
@SecurityScheme | API 보안 스키마를 정의합니다. 인증 방식 등을 설정할 수 있습니다. | 클래스 레벨 |
@SecurityRequirement | 특정 API 엔드포인트에 대한 보안 요구사항을 정의합니다. | 클래스 또는 메서드 레벨 |
2. Swagger 설정 메서드 종류 : Info 클래스
메서드 | 반환 타입 | 분류 | 설명 |
title(String title) | Info | 클래스 정보 설정 | API 제목을 설정합니다. |
version(String version) | Info | 클래스 정보 설정 | API 버전을 설정합니다. |
description(String description) | Info | 클래스 정보 설정 | API 설명을 설정합니다. |
contact(Contact contact) | Info | 클래스 정보 설정 | 연락처 정보를 설정합니다. |
license(License license) | Info | 클래스 정보 설정 | 라이선스 정보를 설정합니다. |
summary(String summary) | Info | 클래스 정보 설정 | API 요약을 설정합니다. |
extensions(Map<String, Object> extensions) | Info | 클래스 정보 설정 | 확장 정보를 설정합니다. |
addExtension(String name, Object value) | void | 클래스 정보 설정 | 확장 정보를 추가합니다. |
addExtension31(String name, Object value) | void | 클래스 정보 설정 | OpenAPI 3.1 확장 정보를 추가합니다. |
setContact(Contact contact) | void | 클래스 정보 설정 | 연락처 정보를 설정합니다. |
setDescription(String description) | void | 클래스 정보 설정 | API 설명을 설정합니다. |
setExtensions(Map<String, Object> extensions) | void | 클래스 정보 설정 | 확장 정보를 설정합니다. |
setLicense(License license) | void | 클래스 정보 설정 | 라이선스 정보를 설정합니다. |
setSummary(String summary) | void | 클래스 정보 설정 | API 요약을 설정합니다. |
setTermsOfService(String termsOfService) | void | 클래스 정보 설정 | 서비스 약관 URL을 설정합니다. |
setTitle(String title) | void | 클래스 정보 설정 | API 제목을 설정합니다. |
setVersion(String version) | void | 클래스 정보 설정 | API 버전을 설정합니다. |
termsOfService(String termsOfService) | Info | 클래스 정보 설정 | 서비스 약관 URL을 설정합니다. |
getSummary() | String | 클래스 정보 조회 | API 요약을 반환합니다. |
getLicense() | License | 클래스 정보 조회 | 라이선스 정보를 반환합니다. |
getContact() | Contact | 클래스 정보 조회 | 연락처 정보를 반환합니다. |
getDescription() | String | 클래스 정보 조회 | API 설명을 반환합니다. |
getExtensions() | Map<String, Object> | 클래스 정보 조회 | 확장 정보를 반환합니다. |
getTermsOfService() | String | 클래스 정보 조회 | 서비스 약관 URL을 반환합니다. |
getTitle() | String | 클래스 정보 조회 | API 제목을 반환합니다. |
getVersion() | String | 클래스 정보 조회 | API 버전을 반환합니다. |
equals(Object o) | boolean | 기본 메서드 | 객체 비교를 수행합니다. |
hashCode() | int | 기본 메서드 | 해시 코드를 반환합니다. |
toString() | String | 기본 메서드 | 객체를 문자열로 변환합니다. |
반응형
5) SpringDoc OpenAPI Starter WebMVC UI 환경 설정
💡SpringDoc OpenAPI Starter WebMVC UI 환경 설정
- 최신 프로젝트로 설치를 하는 경우, Spring Boot 3.x 버전이상이 기본적으로 적용되기에 이에 따라 최신버전에 대해 설정을 하는 방법에 대해 알아봅니다.
1. 개발환경
개발환경 | 버전 |
java | 17 |
Spring Boot | 3.2.5 |
빌드관리도구 | Gradle 8.7 |
개발 툴 | IntelliJ IDEA 2024.1 |
Swagger | 3 |
SpringDoc OpenAPI Starter WebMVC UI | 2.6.0 |
2. 빌드 관리도구에 라이브러리 추가
💡빌드 관리도구에 라이브러리 추가
- build.gradle 파일 내에 라이브러리를 추가하고 빌드합니다.
dependencies {
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0" // Swagger UI
}
Maven Repository: org.springdoc » springdoc-openapi-starter-webmvc-ui
3. Config 파일 구성 : SwaggerConfig
💡Config 파일 구성
- Swagger로 구성하는 API 문서의 제목, 버전, 설명에 대해서 설정합니다.
- 즉, "데모 프로젝트 API Document"라는 제목, "v0.0.1" 버전, 그리고 "데모 프로젝트의 API 명세서입니다."라는 설명을 가진 API 문서를 생성합니다.
package com.adjh.springboot3tierform.config;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Swagger springdoc-ui 구성 파일
*/
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI openAPI() {
Info info = new Info()
.title("데모 프로젝트 API Document")
.version("v0.0.1")
.description("데모 프로젝트의 API 명세서입니다.").
return new OpenAPI()
.components(new Components())
.info(info);
}
}
4. application.properties 파일 지정
💡application.properties 파일 지정
- SpringDoc OpenAPI Starter WebMVC UI를 구성하기 위한 환경 파일입니다.
# Swagger springdoc-ui Configuration
springdoc:
packages-to-scan: com.adjh.springboot3tierform
default-consumes-media-type: application/json;charset=UTF-8
default-produces-media-type: application/json;charset=UTF-8
cache:
disabled: true # 캐시 사용 여부
api-docs:
path: /api-docs/json
groups:
enabled: true
swagger-ui:
enabled: true # Swagger UI 사용여부 : 접근 경로 => <http://localhost:8080/swagger-ui/index.html>
path: /demo-ui.html # Swagger UI 추가 접근 경로 => <http://localhost:8080/demo-ui.html>
tags-sorter: alpha # alpha: 알파벳 순 태그 정렬, method: HTTP Method 순 정렬
operations-sorter: alpha # alpha: 알파벳 순 태그 정렬, method: HTTP Method 순 정렬
💡Swagger 설정에 필요한 주요한 속성들입니다
- 해당 속성들은 일부만 포함하고 있습니다. (* 추가 속성에 대해 궁금하시면 하단의 공식사이트 API Document를 참고하시면 도움이 됩니다)
설정 | default | 설명 | 사용예시 |
springdoc.packages-to-scan | * | 스캔할 패키지를 지정합니다. | com.example.myapp |
springdoc.default-consumes-media-type | application/json | 기본 요청 미디어 타입을 지정합니다 | application/json;charset=UTF-8 |
springdoc.default-produces-media-type | / | 기본 응답 미디어 타입을 지정합니다 | application/json;charset=UTF-8 |
springdoc.cache.disabled | false | 캐시 사용 여부를 지정합니다 | true |
springdoc.api-docs.path | /v3/api-docs | API 문서 JSON 경로를 지정합니다 | /api-docs |
springdoc.api-docs.groups.enabled | false | API 문서 그룹 기능 활성화를 지정합니다 | true |
springdoc.swagger-ui.enabled | true | Swagger UI 사용 여부를 지정합니다 | true |
springdoc.swagger-ui.path | /swagger-ui.html | Swagger UI 접근 경로를 지정합니다 | /swagger-ui |
springdoc.swagger-ui.tags-sorter | alpha | 태그 정렬 방식을 지정합니다 | alpha |
springdoc.swagger-ui.operations-sorter | alpha | 작업 정렬 방식을 지정합니다 | method |
springdoc.paths-to-match | /** | 문서화할 API 경로 패턴을 지정합니다 | /api/, /public/ |
springdoc.packages-to-exclude | 문서화에서 제외할 패키지를 지정합니다 | com.example.internal | |
springdoc.paths-to-exclude | 문서화에서 제외할 API 경로를 지정합니다 | /admin/*, /error |
[ 더 알아보기 ]
💡springdoc.cache.disabled 속성에 대해서 각각 true / false를 하였을 때 어떻게 적용되는가?
1. cache.disabled = false
- Swagger UI와 API 문서가 캐시 됩니다.
- 초기 로딩 후 페이지 접근 속도가 향상됩니다.
- API 변경사항이 즉시 반영되지 않을 수 있습니다.
- 서버 리소스 사용이 줄어듭니다.
2. cache.disabled = true
- Swagger UI와 API 문서가 매 요청마다 새로 생성됩니다.
- 항상 최신 API 정보를 반영합니다.
- 페이지 로딩 시간이 상대적으로 길어질 수 있습니다.
- 서버 리소스 사용이 증가할 수 있습니다.
- 개발 환경에서는 true로 설정하여 변경사항을 즉시 확인하고, 프로덕션 환경에서는 false로 설정하여 성능을 최적화하는 것이 일반적입니다.
💡[참고] 위에 yml 파일에 대한 설정은 application.properties 파일 내에서 loc(로컬), stg(스테이징), prd(운영)을 분리하여서 관리하기 위해 최신 yml 파일을 이용하여 구성한 내용입니다.
- 아래의 분리 방법은 아래의 글을 참고하시면 도움이 됩니다
5. TestController 구성 예시
💡TestController 구성 예시
- REST API Controller 내에서 사용할 수 있는 Swagger Annotation을 적용하여 구성하였습니다.
💡예시에서 사용한 Swagger 주요 어노테이션입니다.
Annotation | 설명 |
@Tag | API 그룹을 정의합니다. 여기서는 "Code-Controller"라는 이름으로 코드 관리 API 엔드포인트를 그룹화했습니다. |
@Operation | API 작업의 설명을 제공합니다. 각 메서드에 대한 요약과 상세 설명을 포함합니다. |
@ApiResponse | API 응답에 대한 정보를 제공합니다. 응답 코드, 설명, 응답 내용 등을 정의합니다. |
@Parameter | API 메서드의 파라미터에 대한 설명을 추가합니다. |
@Schema | API 요청 또는 응답의 스키마를 정의합니다. 주로 DTO 클래스에 사용됩니다. |
@Hidden | 특정 API 엔드포인트를 Swagger 문서에서 숨깁니다. |
@SecurityScheme | API 보안 스키마를 정의합니다. 주로 인증 방식(예: JWT)을 설정할 때 사용됩니다. |
@SecurityRequirement | 특정 API 작업에 보안 요구사항을 적용합니다. @SecurityScheme와 함께 사용하여 인증이 필요한 엔드포인트를 지정합니다. |
💡구성 예시 설명
1. @Tag
- 해당 어노테이션을 통해서 Controller에 대한 설명을 작성하였습니다.
- name 속성을 통해 Controller 이름을 정의하였고, description 속성을 통해 Controller의 상세 설명을 정의하였습니다.
2. @Operation
- 해당 어노테이션을 통해서 메서드에 대한 설명을 작성하였습니다.
- summary 속성을 통해 메서드의 요약 정보를 정의하였고 , description 속성을 통해 메서드의 상세 설명을 정의하였습니다.
3. @ApiResponse
- 해당 어노테이션을 통해 메서드에 대한 API 응답 값을 정의하였습니다.
- responseCode 속성을 통해 정상 통신을 하였을 때 받는 응답 코드 값을 정의하고 , description 속성을 통해 통신 응답에 대한 설명을 정의하고, content 속성을 통해 통신 성공 시 정상적 통신일 때 받을 값을 정의하였습니다.
4. @RequestParam @Parameter
- @Parameter 어노테이션을 통해, @RequestParam으로 전달받은 값에 대해서 API 통신에서 파라미터로 전달받을 값에 대해 정의하였습니다.
- description 속성을 통해서 파라미터에 대한 상세 설명을 정의하였습니다.
5. @RequestBody @Schema
- @Schema 어노테이션을 통해, @RequestBody으로 전달받을 객체 값에 대해 API 통신에서 받을 값에 대해 정의하였습니다.
- implementation 속성을 통해, 전달받을 객체에 대한 상세 정의를 하였습니다.
6. @Hidden
- @Hidden 어노테이션을 통해 Swagger API 정의 내용에서 제외를 하도록 정의하였습니다.
[ Spring Security를 사용하는 경우 ]
7. @SecurityScheme
- 해당 어노테이션을 통해서 Controller를 이용할 때 JWT를 통해서 bearer 인증 방식으로 접근이 가능함을 정의하였습니다.
- name 속성을 통해 인증 방식을 정의하고, type 속성을 통해 통신 타입을 지정하였습니다.
- scheme 속성을 통해 인증 방식을 정의하고 , bearerFormat 속성을 통해 어떤 인증 방식을 이용할지 정의하였습니다.
8. @SecurityRequirement
- 해당 어노테이션을 통해 메서드에서 인증이 필요함을 정의하였습니다.
- 해당 인증으로는 name을 bearerAuth로 지정하여 @SecurityScheme 정의한 name과 매핑이 되도록 구성하였습니다.
package com.adjh.springboot3tierform.controller;
import com.adjh.springboot3tierform.model.dto.CodeDto;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* 코드를 관리하는 Controller
*
* @author : jonghoon
* @fileName : TestController
* @since : 9/7/24
*/
@Tag(name = "Code-Controller", description = "Code 관리 API 엔드포인트")
//@SecurityScheme(name = "bearerAuth", type = SecuritySchemeType.HTTP, scheme = "bearer", bearerFormat = "JWT")
@RestController
public class CodeController {
/**
* 코드 단건 조회
*
* @param codeSq
* @param codeNm
* @return
*/
@GetMapping("/code")
@Operation(summary = "코드 단건 조회", description = "코드 단건을 조회합니다.")
// @SecurityRequirement(name = "bearerAuth")
@ApiResponse(responseCode = "200", description = "성공",
content = @Content(schema = @Schema(implementation = CodeDto.class))
)
public ResponseEntity<List<CodeDto>> selectCode(
@RequestParam @Parameter(description = "코드 시퀀스") int codeSq,
@RequestParam @Parameter(description = "코드 이름") String codeNm
) {
List<CodeDto> temp = new ArrayList<>();
return new ResponseEntity<>(temp, HttpStatus.OK);
}
/**
* 코드 리스트 조회
*
* @param codeDto
* @return
*/
@PostMapping("/code")
@Operation(summary = "코드 리스트 조회", description = "코드 리스트를 조회합니다.")
// @SecurityRequirement(name = "bearerAuth")
@ApiResponse(
responseCode = "200",
description = "성공",
content = @Content(schema = @Schema(implementation = CodeDto.class))
)
public ResponseEntity<CodeDto> selectCodeList(
@RequestBody @Schema(implementation = CodeDto.class) CodeDto codeDto
) {
CodeDto result = CodeDto.builder().build();
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* 코드 전체 수정
*
* @param codeDto
* @return
*/
@PutMapping("/code")
@Operation(summary = "코드 전체 수정", description = "코드를 전체 수정 합니다.")
// @SecurityRequirement(name = "bearerAuth")
@ApiResponse(responseCode = "200", description = "성공")
public ResponseEntity<Integer> updateCode(
@RequestBody @Schema(implementation = CodeDto.class) CodeDto codeDto
) {
int result = 0;
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* 코드 일부 수정
*
* @param codeDto
* @return
*/
@PatchMapping("/code")
@Operation(summary = "코드 일부 수정", description = "코드를 일부 수정 합니다.")
// @SecurityRequirement(name = "bearerAuth")
@ApiResponse(responseCode = "200", description = "성공")
public ResponseEntity<Integer> patchCode(
@RequestBody @Schema(implementation = CodeDto.class) CodeDto codeDto
) {
int result = 0;
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* 코드 삭제
*
* @param codeDto
* @return
*/
@DeleteMapping("/code")
@Operation(summary = "코드 삭제", description = "코드를 삭제합니다.")
// @SecurityRequirement(name = "bearerAuth")
@ApiResponse(responseCode = "200", description = "성공")
public ResponseEntity<Integer> deleteCode(
@RequestBody @Schema(implementation = CodeDto.class) CodeDto codeDto
) {
int result = 0;
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* 사용자 코드 조회 (API Document) 제외
*
* @param codeDto
* @return
*/
@PostMapping("/codes")
@Hidden
@Operation(summary = "사용자 코드 조회", description = "사용자 코드를 조회합니다.")
// @SecurityRequirement(name = "bearerAuth")
@ApiResponse(responseCode = "200", description = "성공")
public ResponseEntity<Integer> selectUserCode(
@RequestBody @Schema(implementation = CodeDto.class) CodeDto codeDto
) {
int result = 0;
return new ResponseEntity<>(result, HttpStatus.OK);
}
}
6. Dto 구성 예시
💡Dto 구성 예시
- REST API에서 데이터를 주고받을 수 있는 DTO에 대해 Swagger Annotation을 적용하여 구성하였습니다.
Annotation | 설명 |
@Schema | API 요청 또는 응답의 스키마를 정의합니다. 주로 DTO 클래스에 사용됩니다. |
💡구성 예시 설명
1. @Schema
- 해당 어노테이션을 통해서 DTO 전체에 대한 설명과 각각 컬럼이 되는 멤버변수에 대해서 설명을 정의하였습니다.
- description 속성을 이용하여서 각각 전체에 대한 설명과 멤버 변수에 대해서 설명을 지정하였습니다.
package com.adjh.springboot3tierform.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* 코드 관리 DTO
*
* @author : jonghoon
* @fileName : CodeDto
* @since : 9/7/24
*/
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Schema(description = "코드 관리 DTO")
public class CodeDto {
@Schema(description = "코드 시퀀스")
private int codeSq;
@Schema(description = "코드")
private String code;
@Schema(description = "코드명")
private String codeNm;
@Schema(description = "코드 타입")
private String codeType;
@Builder(toBuilder = true)
public CodeDto(int codeSq, String code, String codeNm, String codeType) {
this.codeSq = codeSq;
this.code = code;
this.codeNm = codeNm;
this.codeType = codeType;
}
}
6) 설정 결과 확인
1. 서버를 실행하고 지정한 경로로 접근합니다.
💡 서버를 실행하고 지정한 경로로 접근합니다.
- springdoc.swagger-ui.path 속성 값으로 지정한 /demo-ui.html 경로로 접근을 합니다.
- http://localhost:8080/demo-ui.html 경로 접근하며 http://localhost:8080/swagger-ui/index.html 경로로 리다이렉트 됩니다.
💡구성확인
1. 첫 번째 블록은 SwaggerConfig를 통해서 지정한 타이틀과 설명을 지정한 내용이 출력되고 있습니다.
2. 두 번째 블록에서는 Controller에서 정의한 내용들이 출력되고 있습니다
💡최하단을 확인하면 아래와 같이 지정한 DTO까지 출력을 확인할 수 있습니다.
2. API에 대해 확인해 봅니다
💡각각 API에 대해 확인해 봅니다
1. 첫 번째, 두 번째 블록 : @Operation(summary = "코드 단건 조회", description = "코드 단건을 조회합니다.")
- 확인되는 것과 같이 각각 요약과 상세 설명이 출력이 잘됨을 확인하였습니다.
2. 세 번째 블록 : @RequestParam @Parameter(description = "코드 시퀀스") int codeSq,
- 확인되는 것과 같이 파라미터를 정의한 내용이 출력이 잘됨을 확인하였습니다.
3. 네 번째 블록 : @ApiResponse(responseCode = "200", description = "성공", content = @Content(schema = @Schema(implementation = CodeDto.class)) )
- 확인되는 것과 같이 응답 값으로 지정한 내용이 출력이 잘됨을 확인하였습니다.
/**
* 코드 단건 조회
*
* @param codeSq
* @param codeNm
* @return
*/
@GetMapping("/code")
@Operation(summary = "코드 단건 조회", description = "코드 단건을 조회합니다.")
// @SecurityRequirement(name = "bearerAuth")
@ApiResponse(responseCode = "200", description = "성공",
content = @Content(schema = @Schema(implementation = CodeDto.class))
)
public ResponseEntity<List<CodeDto>> selectCode(
@RequestParam @Parameter(description = "코드 시퀀스") int codeSq,
@RequestParam @Parameter(description = "코드 이름") String codeNm
) {
List<CodeDto> temp = new ArrayList<>();
return new ResponseEntity<>(temp, HttpStatus.OK);
}
3. 정의한 Swagger API Document에 대해 JSON 파일 Export를 확인합니다.
💡 정의한 Swagger API Document에 대해 JSON 파일 Export를 확인합니다.
- API Gateway내에 구성한 Swagger 문서에 대해 일괄 Import 하기 위해 이를 활용합니다.
- 아래의 버튼을 선택합니다.
💡아래와 같이 구성한 API 문서가 JSON 형태로 출력됨을 확인할 수 있습니다.
💡pretty print 적용 버튼을 누르면 아래와 같이 정리된 JSON을 확인할 수 있습니다.
💡 [참고] 해당 글은 다음 글에서 이어집니다.
오늘도 감사합니다. 😀
반응형