Swagger는 API를 호출하는 Controller 및 Model에 몇가지 설정만 추가해주면, 직접 작성하지 않아도 편리하게 Rest API를 문서화해줍니다.
Swagger를 이용해 API문서를 생성하는 과정을 기록해보겠습니다.
0️⃣ 환경
- Spring Boot 2.7
- Spring security
- gradle
1️⃣ Swagger 종속성
build.gradle에 Swagger 라이브러리를 사용하기 위해 종속성을 추가해줍니다.
implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '3.0.0'
멀티 모듈로 프로젝트를 구성한 경우, swagger는 api 명세서의 역할을 하기 때문에 api 모듈에만 swagger 종속성을 추가해주면 됩니다.
2️⃣ Swagger 설정 파일
@Configuration
public class SwaggerConfig {
// 이부분은 yml이나 properties에 작성한 뒤 주입받아도 됩니다.
private static final String API_NAME = "프로젝트 이름";
private static final String API_VERSION = "1.0";
private static final String API_DESCRIPTION = "프로젝트 api 명세서";
private static final String SECURITY_SCHEME_NAME = "Authorization";
@Bean
public Docket api(TypeResolver typeResolver){
return new Docket(DocumentationType.SWAGGER_2)
.securityContexts(List.of(securityContext()))
.securitySchemes(List.of(apiKey()))
.additionalModels(typeResolver.resolve(ExceptionResponse.class))
.ignoredParameterTypes(AuthenticationPrincipal.class)
.ignoredParameterTypes(Principal.class)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.mmd"))
.paths(PathSelectors.any())
.build();
}
/* spring security 관련 설정 1 */
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.build();
}
/* spring security 관련 설정 2 */
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "master access");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return List.of(new SecurityReference(HttpHeaders.AUTHORIZATION, authorizationScopes));
}
/* spring security 관련 설정 3 */
private ApiKey apiKey() {
return new ApiKey(HttpHeaders.AUTHORIZATION, HttpHeaders.AUTHORIZATION, "header");
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title(API_NAME)
.version(API_VERSION)
.description(API_DESCRIPTION)
.build();
}
@Bean
public OpenAPI swaggerApi() {
return new OpenAPI()
.components(new Components()
.addSecuritySchemes(SECURITY_SCHEME_NAME, new SecurityScheme()
.name(SECURITY_SCHEME_NAME)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")))
.addSecurityItem(new SecurityRequirement().addList(SECURITY_SCHEME_NAME))
.info(new Info()
.title(API_NAME)
.description(API_DESCRIPTION)
.version(API_VERSION));
}
}
✔️ Docket: 기본 swagger 설정
apiInfo()
제목, 설명 등 문서에 대한 정보들을 설정합니다.
작성 가능한 파라미터로는 title, description, version, termsOfServiceUrl, contact, license, licenseUrl, vendorExtensions 가 있습니다.
apis()
api 스펙이 작성되어 있는 패키지를 지정합니다. 즉, 컨트롤러가 존재하는 패키지를 api 문서화합니다.
paths()
apis()로 선택된 api중 특정 path 조건에 맞는 api들을 다시 필터링하여 문서화합니다.
select()
apiSelectorBuilder를 생성해 apis()와 paths()를 사용할 수 있게 해줍니다.
✔️ Spring Security 설정
security를 설정한 경우, 예외로 지정한 uri를 제외한 모든 uri는 security filter를 타게 됩니다.
이 filter는 header에서 Authorization으로 저장된 값을 검사해서 유효한 토큰값이 아니라면 접근을 못하게 차단하는 역할을 합니다.
Swagger 설정 시 위와 같은 security와 관련된 설정을 추가해주면, API 호출 시 Authorization 헤더에 값을 지정해줄 수 있습니다.
securityContexts
인증 방식을 설정합니다.
securitySchemes
apiKey() : swagger 내에서 인증하는 방식을 지정합니다. 특정 http 헤더에 특정한 문자열 설정 할 수 있습니다. security와 관련해서는 Authorization 헤더를 설정할 수 있습니다.
ignoredParameterTypes
Swagger API 문서의 파라미터에서 설정된 파라미터를 무시합니다.
Security를 사용해서 로그인 처리를 하면, @Principal 이나 @AuthenticationPrincipal 파라미터를 통해 Controller에서 쉽게 로그인된 사용자의 정보를 알아올 수 있습니다.
이 때 사용되는 security 관련 파라미터를 굳이 API 문서에 노출할 필요가 없기 때문에, ignore로 설정해주면 관련 파라미터가 노출되지 않습니다.
✔️ response 설정
additionalModels
직접 지정한 ResponseType을 Swagger에서 응답으로 설정하기 위해서 사용됩니다. 저는 예외 응답을 통일하여 Response DTO를 사용했기 때문에 swagger에 지정해주었습니다.
3️⃣ Controller 적용
@Api
@Api(tags = "다이어리 API")
public class DiaryController { ... }
Swagger 리소스로 사용될 클래스를 마킹합니다.
@ApiOperation
@ApiOperation(value = "모든 다이어리 목록 조회", notes = "로그인한 사용자가 접근할 수 있는 다른 사용자의 다이어리 목록을 페이징 조회합니다.", tags = "다이어리 API")
public ResponseEntity<List<DiaryResponse.FindDiaries>> findAllDiaries() { ... }
클래스에 작성된 http method Api에 대한 설명을 작성합니다.
@ApiImplicitParams
@ApiImplicitParams({
@ApiImplicitParam(name = "memberId", value = "조회할 유저", example = "7", paramType = "path"),
@ApiImplicitParam(name = "request", value = "페이징 request", paramType = "query")
})
public ResponseEntity<List<DiaryResponse.FindDiaries>> findMemberDiaries() { @PathVariable Long memberId, ... }
Api 의 파라미터를 작성합니다. @PathVariable이나 @RequestParam처럼 Api마다 다른 파라미터를 받는 경우 해당 파라미터에 대한 설명을 작성할 수 있습니다.
4️⃣ Model(DTO) 적용
Model, 즉 DTO 클래스에 적용하여 파라미터에 대한 정보를 추가할 수 있습니다.
@ApiModel
@ApiModel(description="다이어리 request")
public class CreateDiary { ... }
Swagger model이 될 클래스의 정보를 추가합니다.
@ApiModelProperty
@ApiModel(description="다이어리 request")
public class CreateDiary {
@ApiModelProperty(value="제목", required=true, example="오늘의 일기")
@NotBlank
private String subject;
}
model 클래스의 파라미터에 대한 설명을 작성합니다.
5️⃣ Swagger 테스트하기
spring boot 프로젝트를 띄운 뒤, http://localhost:8080/swagger-ui/index.html#/ 페이지로 이동하면 현재 Swagger 설정한 Api 문서를 확인할 수 있습니다.
'프로젝트 Project' 카테고리의 다른 글
MSA 앱 만들기 - 2. 로드밸런서 : 서비스 디스커버리 Eureka (1) | 2025.01.06 |
---|---|
API 명세서 - Swagger + Rest Docs (4) | 2024.08.06 |
테스트코드 작성하기 (0) | 2024.08.06 |
OAuth2 로그인 구현하기 (2) | 2024.08.06 |
Spring Security + JWT로 로그인 구현하기 (2) (1) | 2024.08.06 |