kkokkio - 프로젝트/트러블슈팅

SpringDocs에서 SwaggerConfig보다 yaml이 우선되는가?

파란배개 2025. 6. 2. 10:12

문제 개요

오류 상황과 영향 범위 (예: 특정 코드 실행 시 발생, 특정 라이브러리 버전 호환 문제 등) 발생 배경 (예: 코드 테스트 중, 배포 중 문제 발견 등)

  • 로컬 환경에서는 잘 작동하던 swagger가 HTTPS로 배포된 서버에서 Swagger 페이지는 https로 접속이 가능했으나 Swagger UI 드롭다운에 표시된 URL은 여전히 http 로 나타나 API 요청 역시 http로 하고 있었다.

오류 메시지 및 원인 분석

오류 코드, 오류 메시지 포함 HTTP 상태 코드, 애플리케이션 로그, 서버 로그 등 구체적인 오류 정보 정리 및 로그 메시지를 통한 분석 제공 문제 발생 원인에 대한 심층 분석

  • swagger는 기본적으로 http 프로토콜을 사용하기 때문에 CORS 문제가 발생하는 것을 파악했다

해결 및 고민 과정

처음 문제를 접했을 때 고려했던 대안들과 선택하지 않은 이유 실험적으로 적용한 방법이 실패한 사례와 그 이유 여러 해결책 중 최적의 방안을 선택한 과정

  • 해결책을 찾던 중 SwaggerConfig에서 OpenApi에 서버 주소를 설정해 주면 되는 것을 알았다.
@Configuration
public class SwaggerConfig {
    @Bean
    public OpenAPI openAPI() {
        Info info = new Info()
            .title("꼬끼오 API")
            .version("Ver 1.0")
            .description("프로젝트 '꼬끼오' 서비스의 백엔드 API 명세서입니다.");

				return new OpenAPI()
            .info(info)
            //이런 식으로 servers에 주소 입력
            .servers(List.of(new Server().url("<https://api.deploy.kkokkio.site>"))); 
    }
  • 그러나 해결되지 않았다
    • 프로토콜을 넣고 빼고, 포트를 넣고 빼고 이것저것 해보았지만 원하는 https 프로토콜 주소로 작동하지 않았다.
  • Spring Boot + SpringDoc(OpenAPI) 설정 시, 코드(SwaggerConfig)와 YAML 설정을 함께 사용하여 서버 URL을 동적으로 주입한다는 것을 알았다.
    • 초기 코드에는 OpenAPI만 등록되어 있고, YAML 설정 없이 동작했지만, https를 적용하기 위해 코드를 변경하는 과정에서 YAML 설정이 추가되었다.
    • 문제는 코드와 YAML 설정 사이에서는 YAML 설정의 우선도가 높아 코드에서 주소를 아무리 바꿔도 YAML 설정으로 주입된 URL이 적용되었던 것이다.
  • SpringDoc의 auto‐configuration 모듈이 자동으로 YAML 설정을 읽어들이기 때문에 Swagger UI는 그 값을 기준으로 동작한다고 한다.
    • 즉, 애초에 SwaggerConfig 안에서 서버 URL을 설정하지 않았어도, SpringDoc이 제공하는 Swagger UI 설정 빈이 이미 application.yml에 있는 URL을 갖고 있기 때문에 UI에는 그 값이 들어간거라고 한다.

참고: Path와 ConfigUrl 설정

  • 문제를 해결하기 위해 설정을 변경하던 중 결과적으로 문제와 상관은 없었지만 Path와 ConfigUrl의 설정 변경도 알아보고 시도해서 적어놓는다.
    • Path는 swagger UI가 제공하는 접근 경로를 기본 경로에서 특정 경로로 접근 경로를 변환하는 설정이다.
      • 기본 경로가 swagger-ui/index.html 이라면, 다음과 같은 설정으로 swagger UI 주소는 도메인/api-docs0-ui 로 변경된다.
      springdoc:
        swagger-ui:
          path: /api-docs-ui
      
      • 주로 경로 통일이 필요하거나 기존 경로와의 충돌 회피, 보안을 위해 경로를 숨길 때 사용한다.
    ConfigUrl
    • ConfigUrl은 swagger UI의 부트스트랩 설정을 가져오는 엔드포인트URL을 변경한다.
      • 기본 경로가 /v3/api-docs/swagger-config라면, 다음과 같은 설정으로 swagger UI는 도메인/custom-config으로 요청하게 된다.
      springdoc:
        swagger-ui:
          config-url: /custom-config
      
    • 이 설정을 사용하면 커스텀 컨트롤러를 통해 인증, 인가를 거쳐 사용이 가능하다.
  • Path
  • 두 설정이 비슷해 보이는데, Path는 UI 자체가 어느 URL에 매핑될지를 설정하는 것이고, ConfigUrl은 swagger UI가 내부 설정을 어디서 로딩할지를 지정한다는 차이점이 있다.
springdoc:
  swagger-ui:
    config-url: /custom-config 

최종 해결책 및 구현

문제 해결을 위한 단계별 조치 방법과 코드 예시 (예: 특정 애노테이션 추가, 라이브러리 버전 조정, 설정 변경 등) 참고 자료 (관련 공식 문서, 개발자 커뮤니티 게시물 등)

프로필 별 YAML 설정 분리

  • swagger 설정에서 path와 configUrl을 건들지 않고 url만 변경
    • application.yml (기본)
    swagger:
      url: <http://localhost:8080>
    
    • application-dev.yml
    swagger:
      url: <https://api.deploy.kkokkio.site>
    
    • application-prod.yml
    swagger:
      url: <https://api.prd.kkokkio.site>
    

YAML로 환경에 따라 환경변수 주입

@Configuration
public class SwaggerConfig {
		//환경별로 분리된 YAML 설정에서 URL을 주입받음
    @Value("${swagger.url}")
    private String swaggerServerUrl;

    @Bean
    public OpenAPI openAPI() {
        Info info = new Info()
            .title("꼬끼오 API")
            .version("Ver 1.0")
            .description("프로젝트 '꼬끼오' 서비스의 백엔드 API 명세서입니다.");

        return new OpenAPI()
            .info(info)
            .servers(List.of(new Server().url(swaggerServerUrl)));
    }
}

결과 및 성능 분석

개선 후 응답 속도, DB 부하 감소 수치 등 구체적인 데이터 포함 문제 해결 전/후 성능 비교 그래프나 로그 분석 내용 포함 이슈 트래킹 및 자동화 방안 추가 (내부 개발자가 반복적인 문제 해결을 효율적으로 관리할 수 있도록 가이드 제공)

앞선 해결책으로 인해 스웨거가 잘 작동했다.

추가 개선점

유사한 문제를 방지하기 위한 주의할 점 (예: 애노테이션 명시 여부, 프레임워크 업데이트 주기 확인 등) 문제 해결 과정에서 배운 점 및 중요한 교훈 공유 보안 고려 사항 추가 (해결 과정에서 발생할 수 있는 보안 리스크 및 예방 조치 포함)

Swagger UI 설정(urls, config-url)은 YAML에서 완전 관리하고, 코드에서는 OpenAPI.servers로만 서버 URL을 주입하는 방식이 충돌을 피할 수 있다.

ConfigUrl 설정으로 보안을 향상시킬 수 있을 것으로 보인다.