2024.12.12
목차

기존에 Spring Boot 프로젝트에서 Swagger UI 사용하여 API 문서를 제공하고 있었다. 서버 이전 이후로 사용하지 않아서 인식하지 못하다가 최근에 Swagger가 제대로 작동하지 않는다는 문제를 발견했다. 그래서 오류도 고치고 Swagger UI의 가독성과 사용성을 높이기 위해 전체적으로 개선했다.
1. 기존 문제점
기존 SwaggerConfig
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI openAPI() {
SecurityScheme securityScheme = new SecurityScheme()
.type(SecurityScheme.Type.APIKEY)
.in(SecurityScheme.In.HEADER)
.name("Authorization");
SecurityRequirement securityRequirement = new SecurityRequirement()
.addList("Bearer Token");
return new OpenAPI()
.components(new Components())
.info(apiInfo())
.components(new Components().addSecuritySchemes("Bearer Token", securityScheme))
.addSecurityItem(securityRequirement);
}
}
- 태그가 컨트롤러 파일명에 따라 자동으로 그룹화되어 가독성이 떨어졌다.
- 소셜 로그인용 클라이언트 ID와 서비스 액세스 토큰이 구분되지 않아 API 테스트가 어려웠다.
- API 설명이 없어 각 엔드포인트의 용도와 동작 방식을 알기 어려웠다.
2. API 태그 구분과 설명 추가
SwaggerConfig
@Bean
public OpenAPI openAPI() {
// ...
return new OpenAPI()
.info(apiInfo())
// security 설정
.tags(Arrays.asList(
new Tag().name("Auth").description("인증 및 회원 관리 API"),
new Tag().name("User").description("사용자 정보 관리 API"),
new Tag().name("Post").description("게시글 관련 API"),
new Tag().name("App").description("안드로이드 앱 버전 관리 API"),
new Tag().name("Policy").description("정책 관련 API")
));
}
API들을 기능 단위로 명확하게 구분하기 위해 태그를 정의했다.
이렇게 정의하면 Swagger UI에서 태그가 코드 순서대로 표시되고, 관련 API들이 해당 태그 하위에 그룹화된다.
3. 인증 방식 구분
SwaggerConfig
@Bean
public OpenAPI openAPI() {
// 소셜 로그인용 SecurityScheme
SecurityScheme socialAuthScheme = new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.in(SecurityScheme.In.HEADER)
.name("Authorization")
.description("Social Client ID - 소셜 로그인(Google/Apple) 요청 시 사용할 클라이언트 ID를 입력하세요");
// 서비스 액세스 토큰용 SecurityScheme
SecurityScheme accessTokenScheme = new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.in(SecurityScheme.In.HEADER)
.name("Authorization")
.description("Access Token - 소셜 로그인 후 받은 액세스 토큰을 입력하세요");
// 기본적으로 Access Token 사용하도록 설정
SecurityRequirement defaultRequirement = new SecurityRequirement()
.addList("Access Token");
// ...
}
소셜 로그인과 일반 API 호출에서 사용하는 토큰이 다르기 때문에, 두 가지 인증 방식을 구분했다.
Swagger UI에서는 “Authorize” 버튼을 통해 아래의 동작으로 인증을 수행할 수 있다.
- 소셜 로그인 API 호출 시: Social Auth에 Client ID 입력
- 그 외 API 호출 시: Access Token에 로그인 후 받을 토큰 입력
4. API 상세 설명 추가
각 Controller
@Operation(
summary = "Google 로그인", // API 제목
description = "Google 클라이언트 ID를 이용하여 로그인합니다.", // 상세 설명
tags = ("Auth"), // 태그 - API 그룹
security = { @SecurityRequirement(name = "Social Auth") }) // 필요한 인증 방식
@PostMapping("/google")
public ResponseDto<LoginResponseDto> loginUsingGOOGLE(...) throws ... {...}
@Operation(
summary = "정책 목록 조회",
description = "지역과 분류에 따른 정책 목록을 조회합니다.",
tags = {"Policy"})
// security 미지정 시 기본값(Access Token) 사용ㄴ
@GetMapping("")
public ResponseDto<?> getPolicyList(...) {...}
각 API에 @Operation
어노테이션을 사용하여 상세 설명을 추가했다.
@Operation
은 springdoc-open 라이브러리에서 제공하는 어노테이션이다.
summary
: API 제목description
: API 상세 설명tag
: 필요한 인증 방식 지정
5. API 정렬 설정
application.yml
springdoc:
swagger-ui:
operations-sorter: method # HTTP 메소드 순으로 정렬 (DELETE, GET, PATCH, POST, PUT)
Swagger UI 정렬 설정을 yml 파일에 추가했다.
각 태그 내의 API가 HTTP 메소드 알파벳 순(DELETE → GET → PATCH → POST → PUT)으로 정렬된다. 현재 커스텀 정렬을 지원하지 않아서 이 방법을 사용했다.
6. URL 스키마 문제 해결
REF) https://kwakscoding.tistory.com/49
위 작업까지 수행하고 운영 서버에 적용했더니, Swagger UI의 API 요청 URL이 HTTPS가 아닌 HTTP로 생성되는 문제가 발생했다.

Failed to fetch.
Possible Reasons:
CORS
Network Failure
URL scheme must be "http" or "https" for CORS request.


운영 환경에서 API 요청 URL을 https로 지정하기 위해 SwaggerConfig에서 URL을 직접 설정했다.
@Bean
public OpenAPI openAPI() {
// ...
// URL 설정
Server server = new Server().url("https://cheongha.site");
return new OpenAPI()
.info(apiInfo())
.components(new Components()
.addSecuritySchemes("Social Auth", socialAuthScheme)
.addSecuritySchemes("Access Token", accessTokenScheme))
.addSecurityItem(defaultRequirement) // 전역 설정으로 Access Token 사용
.addServersItem(server) // 운영 서버 URL
// ...
}
Server 객체를 만들어서 요청할 URL을 설정해주고 addServersItem으로 추가했다.
로컬 환경에서는 별도의 설정 없이도 localhost:8080 으로 자동 설정되어 추가하지 않았다.
6. 결과
- 명확한 API 그룹화: 기능별로 API가 명확하게 구분되어 원하는 API를 쉽게 찾을 수 있다
- 인증 프로세스 개선:
- 소셜 로그인 시: Social Auth에 클라이언트 ID 입력
- 일반 API 호출 시: Access Token에 로그인 후 받은 토큰 입력
- 이해도 향상: 각 API의 목적과 동작 방식을 명확하게 파악할 수 있다
- 일관된 정렬: HTTP 메소드 순으로 정렬되어 API 목록을 탐색하기 쉬워졌다
/swagger-ui/index.html


REF
https://jeonyoungho.github.io/posts/Open-API-3.0-Swagger-v3/
'Projects > 청하-청년을 위한 커뮤니티 서비스' 카테고리의 다른 글
[청하] TimeFormatter 클래스 리팩토링 (feat. @UtilityClass) (0) | 2025.04.04 |
---|---|
[청하] 밸런스 게임/토론 기능 구현 - (1) 설계 (0) | 2025.04.04 |
[청하] 46. 청년 정책 검색 기능 - (2) 구현 (0) | 2025.02.04 |
[청하] 45. 청년 정책 검색 기능 - (1) 설계 (0) | 2025.02.02 |
[청하] 43. 맞춤 & 핫한 정책 조회 기능 - MySQL의 ONLY_FULL_GROUP_BY 오류 해결 (0) | 2025.01.01 |
댓글