시작하며
API를 개발할 때, 문서화는 매우 중요한 작업 중 하나이다. 특히 여러 명의 개발자가 함께 작업하거나 외부 클라이언트가 API를 사용할 때, 명확하고 잘 정리된 API 문서는 필수이다. 이러한 API 문서를 자동으로 생성하고 관리하는 도구로 Swagger는 매우 유용하다. 이 글에서는 Spring Boot 애플리케이션에서 Swagger를 이용해 API 문서를 설정하고 JWT 인증을 추가하는 방법을 설명하겠다.
1. Swagger 도입 이유
Swagger를 도입하는 이유는 크게 세 가지입니다.
1.1. 기존 API 문서화 방식의 문제점
기존에 프로젝트를 진행할 때 POSTMAN이나 노션 등에 API 문서화를 진행했다.
이렇게 하면 코드를 수정하면 그때그때 문서를 수정해야만 하는데 이 부분은 너무 번거로운면이 많았다.
특히 노션같은 경우 테스트도 바로바로 할 수가 없다는 단점이 있었고 PostMan도 직접 바꿔줘야했기 때문에 문제가 많이 있었다.
1.2. 실시간 인터페이스 제공 및 테스트 기능
Swagger는 애플리케이션의 엔드포인트와 그에 대한 요청/응답 데이터를 자동으로 문서화한다. 이를 통해 API 명세를 따로 관리할 필요
가 없으며, 항상 최신 상태를 유지할 수 있다.
즉, 코드의 데이터를 변경하면 즉시 문서에 반영된다는 것이다.
Swagger UI는 API를 테스트할 수 있는 웹 기반 인터페이스를 제공한다. 이 도구를 사용하면 API 명세를 단순히 읽는 것뿐만 아니라, 즉시 테스트하여 개발 중에도 빠르게 검증할 수 있다.
1.3. 유지보수 용이성
Swagger는 코드와 문서화를 일치시키기 때문에, API가 변경되면 문서도 자동으로 업데이트됩니다. 이로 인해 문서와 실제 API 간의 불일치가 발생할 가능성이 줄어든다.
2. Swagger 설정 방법
2.1. build.gradle에 의존성 추가
먼저 build.gradle 파일에 Swagger 설정을 위해 필요한 의존성을 추가한다.
dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
// 다른 의존성들...
}
위와 같은 의존성을 추가한 후, gradle build를 실행하여 필요한 라이브러리를 다운로드한다.
2.2. SwaggerConfig 클래스 설정
Swagger를 설정하는 SwaggerConfig 클래스를 만들어준다. 이 클래스는 Swagger UI에 표시될 기본 정보와 보안 설정(JWT 인증) 등을 정의합니다.
package com.groomiz.billage.global.config;
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;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI openAPI() {
// API 기본 정보 설정
Info info = new Info()
.title("빌리지 API Document")
.version("1.0")
.description(
"환영합니다! [발리지](https://example.com)는 서울과학기술대학교 강의실을 빌리기 위해 만든 플랫폼입니다. 이 API 문서는 빌리지의 API를 사용하는 방법을 설명합니다.\n")
.contact(new io.swagger.v3.oas.models.info.Contact().email("billage.official@gmail.com"));
// JWT 인증 방식 설정
String jwtScheme = "jwtAuth";
SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtScheme);
Components components = new Components()
.addSecuritySchemes(jwtScheme, new SecurityScheme()
.name("Authorization")
.type(SecurityScheme.Type.HTTP)
.in(SecurityScheme.In.HEADER)
.scheme("Bearer")
.bearerFormat("JWT"));
// Swagger UI 설정 및 보안 추가
return new OpenAPI()
.addServersItem(new Server().url("http://localhost:8080")) // 추가적인 서버 URL 설정 가능
.components(components)
.info(info)
.addSecurityItem(securityRequirement);
}
}
이 설정을 통해 Swagger UI는 API의 정보를 직관적으로 보여주며, JWT 인증을 헤더에서 처리하도록 설정된다.
2.3. application.yml 설정
application.yml 파일에서 Swagger UI의 동작을 세밀하게 조정할 수 있다. 예를 들어, 패키지 스캔 범위와 기본 미디어 타입, Swagger UI의 경로 등을 설정할 수 있다.
springdoc:
packages-to-scan: com.groomiz.billage
default-consumes-media-type: application/json;charset=UTF-8
default-produces-media-type: application/json;charset=UTF-8
swagger-ui:
path: /
disable-swagger-default-url: true
display-request-duration: true
operations-sorter: alpha
- packages-to-scan: Swagger가 문서화할 패키지를 지정합니다.
- default-consumes-media-type 및 default-produces-media-type: API가 소비하고 반환할 기본 미디어 타입을 지정합니다.
- swagger-ui.path: Swagger UI에 접근할 경로를 설정합니다.
3. JWT 인증을 위한 Spring Security 설정
만약 이것만 설정했는데도 localhost:8080으로 접속했을 때 아무 ui가 안 나온다면 안된다면 혹시 스프링 시큐리티가 켜져있는건 아닐지 살펴보자.
이런식으로 403이 나온다면 시큐리티의 권한문제이니 잘 보고 바꿔주자.
컨피그 설정은 팀마다 다르다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@RequiredArgsConstructor
@EnableWebSecurity
@Configuration
public class SecurityConfig {
private final JwtProvider jwtProvider;
private final SecurityProperties securityProperties;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.httpBasic(Customizer.withDefaults()) // HTTP 기본 인증 비활성화
.csrf(Customizer.withDefaults()) // CSRF 보호 비활성화
.cors(Customizer.withDefaults()) // CORS 설정
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 세션 상태 비활성화
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) // 모든 요청 허용
.addFilterBefore(
new JwtAuthenticationFilter(securityProperties.getWhitelist(), jwtProvider),
UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
3.2. SecurityProperties 설정
화이트리스트는 application.yml 또는 application.properties에 설정해줄 수 있다.
실제 적용한 프로젝트별로 다르지만 나는 다음과 같이 화이트리스트 목록을 받아서 진행헀다.
@Component
@ConfigurationProperties(prefix = "security")
@Getter
@Setter
public class SecurityProperties {
private List<String> whitelist;
}
이를 통해 특정 경로에 대한 보안을 유연하게 조정할 수 있다.
properties에 whiteList 경로를 적어줘서 사용해줬다.
4. Swagger UI에서 API 문서 확인
모든 설정이 완료된 후 localhost:8080으로 접속하면 Swagger UI가 정상적으로 작동할 것이다. Swagger UI는 아래와 같은 화면을 제공한다.
다음과 같이 스웨거가 나오는 모습을 볼 수 있다.
5. 사용법
이제 사용법에 대해서 알아보자.
5.1 문서화 시작
package com.groomiz.billage.global.document;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
@RestController
@RequestMapping("/v1/example")
@RequiredArgsConstructor
public class ExampleController {
@GetMapping("/global")
public void example() {
}
}
다음과 같은 컨트롤러를 제작하면 아래와 같이 swagger 문서가 만들어진다.
5.2 문서에 설명 추가하기
@RestController
@RequestMapping("/v1/example")
@RequiredArgsConstructor
@Tag(name = "Exception Document", description = "예제 에러코드 문서화")
public class ExampleController {
@GetMapping("/global")
@Operation(summary = "글로벌 (aop, 서버 내부 오류등) 관련 에러 코드 나열")
public void example() {
}
}
다음과 같이 Tag와 Operation 어노테이션을 사용해서 만들 수 있다.
다음과 같이 설명이 추가된 것을 볼 수가 있다.
5.3 요청 응답 예시 Dto 만들기
이제 우리는 성공 데이터 예시, 요청 데이터 예시를 만들어서 문서화를 해보자.
package com.groomiz.billage.global.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "예제 요청 DTO")
public class ExampleReqDto {
@Schema(description = "이름", example = "홍길동")
private String name;
@Schema(description = "나이", example = "20")
private int age;
}
package com.groomiz.billage.global.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "예제 응답 DTO")
public class ExampleResDto {
@Schema(description = "이름", example = "홍길동")
private String name;
@Schema(description = "나이", example = "20")
private int age;
}
다음과 같이 2개의 request용 response용 데이터를 만들어준다.
package com.groomiz.billage.global.document;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.groomiz.billage.global.dto.ExampleReqDto;
import com.groomiz.billage.global.dto.ExampleResDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
@RestController
@RequestMapping("/v1/example")
@RequiredArgsConstructor
@Tag(name = "Exception Document", description = "예제 에러코드 문서화")
public class ExampleController {
@GetMapping("/global")
@Operation(summary = "글로벌 (aop, 서버 내부 오류등) 관련 에러 코드 나열")
public ExampleResDto example(ExampleReqDto exampleReqDto) {
ExampleResDto exampleResDto = new ExampleResDto();
exampleResDto.setName(exampleReqDto.getName());
exampleResDto.setAge(exampleReqDto.getAge());
return exampleResDto;
}
}
다음과 같이 코드를 짜주면 swagger에서 다음과 같이 request와 response에 대한 예시가 나온다.
5.4 스웨거로 테스트 해보기
위쪽에 try it out 버튼을 눌러주면, 다음과 같이 요청 데이터를 바꿀 수 있고 Execute 버튼이 활성화된다.
이후 실행하게 되면, 다음과 같이 결과가 나오게 된다.
이렇게 직접 데이터를 바꿔서 테스트를 해볼 수 있고 example값이 있어서 손 쉽게 테스트를 해볼 수 있다.
5.5스키마 확인하기
다음과 같이 Example Value옆에 Schema를 누르면 각 스키마를 볼 수 있고.
스웨거 아래쪽을 보면 스키마를 볼 수 있다.
마무리
이 글에서는 Spring Boot 프로젝트에 Swagger를 설정하고 JWT 인증을 추가하는 방법에 대해 다뤘다. Swagger는 API 문서화에 있어 매우 유용한 도구로, 특히 API 개발 단계에서 실시간으로 테스트하고 문서를 자동으로 관리할 수 있다는 점에서 큰 장점이 있다.
또한 간단한 사용법에 대해서 알아봤는데, 다음 글에서는 Swagger 어노테이션을 이용해 더 세부적인 문서화를 하는 방법과 에러 처리를 문서화하는 방법에 대해 다루겠다.
'Backend' 카테고리의 다른 글
[spring swagger로 에러문서화하기] 에러 형식 정의 및 handler 정의 (1/2) (0) | 2024.09.21 |
---|---|
[k8s] kubectl 명령어가 동작하지 않을 때 (왜 쿠버네티스는 스왑 메모리 사용을 허용하지 않는가?) (1) | 2024.09.17 |
Aws SQS Spring으로 Listener Stop Start하기 (0) | 2024.08.13 |
sqs spring boot 사용법 (0) | 2024.08.13 |
[문제해결] Spring webSocket Test 삽질 일기 (생성자 직렬화 문제) (0) | 2024.08.07 |