[Spring] Swagger 적용하기
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
스프링 정리를 위한 포스팅입니다.
해당 포스팅은 Swagger 정리입니다.
서론
Swagger는 RESTful API를 웹 단에서 설계, 빌드, 문서화, 테스트하는데 사용하는 도구입니다.
이를 통해서 프론트엔드 개발자와 백엔드 개발자가 효율적으로 협업을 진행할 수 있고, 문서화에도 도움을 줍니다.
Spring Boot와 함께 Swagger를 적용하면 백엔드 개발자는 API 문서를 자동으로 생성하고 팀 간 협업 및 테스트를 효율적으로 진행할 수 있습니다.
해당 포스팅에서는 Swagger와 OpenAPI의 개념, Spring Boot 프로젝트에서 Swagger를 설정하는 방법 등을 소개합니다.
Swagger
Swagger란 무엇인가?
Swagger는 REST API를 문서화하고, API 설계와 구현을 더 쉽게 하기 위해 제공되는 도구입니다.
현재는 OpenAPI Initiative의 표준으로 자리 잡았으며, OpenAPI 스펙 기반으로 API 문서를 자동 생성합니다.
Swagger의 주요 기능
- API 문서화: REST API의 모든 엔드포인트, 메서드, 요청/응답 형식 등을 정리
- Swagger UI 제공: API 테스트와 시뮬레이션을 위한 사용자 인터페이스
- 클라이언트 코드 생성: OpenAPI 스펙을 기반으로 클라이언트 SDK 생성
Spring Boot에서 Swagger 설정하기
- 의존성 추가
Swagger와 OpenAPI를 사용하려면 Spring Boot 프로젝트의 build.gradle 또는 pom.xml에 의존성을 추가해야 합니다.
Gradle 예시
// Swagger
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.6.0'
- 기본 설정
Spring Boot에서는 별도의 설정 없이도 swagger-ui와 OpenAPI 문서를 사용할 수 있습니다.
SpringDoc 라이브러리를 추가하면 /swagger-ui.html 또는 /swagger-ui/index.html 경로에서 Swagger UI에 접근할 수 있습니다.
- SwaggerConfig 설정
SwaggerConfig 클래스는 OpenAPI 문서의 기본적인 설정을 커스터마이징할 수 있도록 작성됩니다.
Spring Boot와 SpringDoc을 사용하면 Swagger UI와 OpenAPI 문서를 별도의 설정 없이 기본적으로 사용할 수 있지만, 프로젝트 이름, API 설명, 버전 정보 등을 명확히 하기 위해 SwaggerConfig 클래스에서 OpenAPI 객체를 설정할 수 있습니다.
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info().title("Hiro Backend")
.description("Hiro Backend 서버")
.version("v0.0.1"));
}
}
만약 JWT 토큰을 사용하고 싶으면?
@Bean
public OpenAPI openAPI() {
SecurityScheme securityScheme = new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
.in(SecurityScheme.In.HEADER)
.name("Authorization");
SecurityRequirement securityItem = new SecurityRequirement().addList("bearerAuth");
return new OpenAPI()
.openapi("3.0.1") // OpenAPI 버전 명시
.components(new Components().addSecuritySchemes("bearerAuth", securityScheme))
.security(List.of(securityItem))
.info(apiInfo());
}
을 추가해주시면 됩니다.
- SecurityScheme 설정
SecurityScheme 객체를 통해 Swagger 문서에 JWT 인증 방식을 정의합니다.- type: 인증 방식의 타입을 설정합니다. 여기서는 HTTP 방식을 사용합니다.
- scheme: bearer로 설정하여 JWT 인증임을 명시합니다.
- bearerFormat: 토큰의 형식을 "JWT"로 지정합니다.
- in: 인증 정보가 포함되는 위치를 지정합니다. JWT 토큰은 보통 HTTP 헤더의 Authorization 필드에 포함됩니다.
- name: 헤더의 이름을 Authorization으로 설정합니다.
- SecurityRequirement 설정
SecurityRequirement 객체는 Swagger 문서에서 JWT 인증이 필요한 엔드포인트에 보안 요구사항을 추가합니다.- addList("bearerAuth"): 위에서 정의한 SecurityScheme을 엔드포인트에 적용합니다.
- Components 설정
OpenAPI의 구성 요소에 SecurityScheme을 추가합니다.- addSecuritySchemes("bearerAuth", securityScheme): bearerAuth라는 이름으로 JWT 인증 스키마를 등록합니다.
- security 설정
- OpenAPI 문서의 기본 보안 요구사항을 정의합니다. 모든 엔드포인트에 기본적으로 JWT 인증이 필요하도록 설정됩니다.
- info() 메서드
API 문서의 제목, 설명, 버전 정보 등을 설정합니다.
API를 기능별로 나누고 싶다면
@Configuration
public class SwaggerConfig {
@Bean
public GroupedOpenApi userApi() {
return GroupedOpenApi.builder()
.group("user-api") // 사용자 관련 API 그룹
.pathsToMatch("/users/**", "/profile/**")
.build();
}
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("admin-api") // 관리자 관련 API 그룹
.pathsToMatch("/admin/**", "/management/**")
.build();
}
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("public-api") // 공개 API 그룹
.pathsToMatch("/public/**", "/auth/**")
.build();
}
/*
* ...
*/
}
- GroupedOpenApi 정의:
- group: Swagger UI에서 보여질 그룹 이름입니다.
- pathsToMatch: 해당 그룹에 포함될 엔드포인트 경로를 지정합니다. /**와 같은 경로 패턴을 사용할 수 있습니다.
- 그룹 나누기:
- user-api: /users/**, /profile/**로 시작하는 엔드포인트를 포함합니다.
- admin-api: /admin/**, /management/**로 시작하는 엔드포인트를 포함합니다.
- public-api: /public/**, /auth/**로 시작하는 엔드포인트를 포함합니다.
- 컨트롤러에 Swagger 어노테이션 추가
컨트롤러에 @Tag, @Operation, @ApiResponse 등 OpenAPI 3 스펙 기반의 애노테이션을 추가하여 API 엔드포인트를 문서화할 수 있습니다.
@RestController
@RequestMapping("/api/users")
@Tag(name = "User API", description = "Operations for managing users")
public class UserController {
@Operation(summary = "Get all users", description = "Retrieve a list of all users.")
@GetMapping
public List<User> getAllUsers() {
return List.of(new User(1L, "John", "john@example.com"));
}
@Operation(summary = "Create a user", description = "Add a new user to the system.")
@ApiResponse(responseCode = "201", description = "User created successfully.")
@PostMapping
public User createUser(@RequestBody User user) {
return user; // For demonstration purposes
}
}
- @Tag
@Tag는 OpenAPI 스펙에서 API의 그룹화를 위한 어노테이션입니다.
주로 컨트롤러 레벨에서 사용되며, Swagger UI에서 API를 그룹별로 정리해서 보여줍니다.- 주요속성
- name: 태그의 이름. Swagger UI에서 그룹명으로 표시됩니다.
- description: 태그에 대한 설명을 작성합니다.
- 주요속성
- @Operation
@Operation은 API 엔드포인트(메서드) 수준에서 사용됩니다.
해당 메서드에 대한 요약, 설명, 요청/응답에 대한 정보 등을 문서화합니다.- 주요속성
- summary: API 엔드포인트에 대한 간단한 설명 (Swagger UI에서 메서드 옆에 표시).
- description: API 엔드포인트에 대한 상세 설명.
- tags: 이 엔드포인트에 추가적으로 적용할 태그 목록. 컨트롤러에 정의된 @Tag와는 별개로 추가 가능.
- parameters: 요청에 필요한 매개변수 정의 (필요시 사용).
- responses: 응답에 대한 설명을 추가 (일반적으로 @ApiResponse와 함께 사용).
- 주요속성
- @ApiResponse
@ApiResponse는 특정 API 엔드포인트의 응답 정보를 문서화하는 데 사용됩니다.
응답 상태 코드와 메시지, 반환되는 데이터에 대한 설명을 추가할 수 있습니다.- 주요속성
- responseCode: HTTP 응답 상태 코드 (예: "200", "404", "500").
- description: 응답에 대한 간단한 설명.
- content: 반환되는 데이터의 형식을 정의 (JSON, XML 등).
- 주요속성
어노테이션 | 설명 | 주요속성 |
@RequestBody | 요청 본문 데이터를 객체로 매핑. Swagger 문서에 요청 본문 설명 추가. | description (설명) required (필수 여부) content (데이터 형식) |
@Parameter | 요청 매개변수(Query, Path, Header 등)를 설명. | name (매개변수 이름) description (설명) required (필수 여부) example (예제 값) |
@Schema | 데이터 모델(엔티티, DTO) 필드의 설명 및 스키마 정의. | description (필드 설명) example (예제 값) required (필수 여부) type (데이터 타입) |
@RequestHeader | 요청 헤더를 정의하고 Swagger 문서에 추가. | name (매개변수 이름) description (설명) required (필수 여부) |
@Content | 요청 또는 응답 본문 데이터의 형식 정의. | mediaType (데이터 형식: JSON, XML 등) schema (데이터 구조) |
결과
localhost:8080/swagger-ui/index.html로 접근하면 Swagger 화면이 렌더링 됩니다.
/json-users를 클릭 후 Execute를 하면
결과가 잘 나오는 것을 확인할 수 있습니다.