- Spring Cloud Gateway에서 마이크로서비스의 Swagger 관리하기
- 의존성 추가
- SwaggerConfig 작성
- gateway application.yml 작성
- 필터를 수행하지 않을 경로 추가
Spring Cloud Gateway에서 각 마이크로서비스들의 Swagger를 통합 관리하는 방법을 알아보았다.
springdoc-openapi를 통해 Swagger를 사용한다.
(Spring Boot 3.4.0, JDK 17 기준)
// swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'
마이크로서비스에서는 위 의존성을 추가한다.
// swagger
implementation 'org.springdoc:springdoc-openapi-starter-webflux-ui:2.7.0'
Gateway는 Webflux를 기반으로 비동기적으로 동작하기 때문에 위 의존성을 추가한다.
각 마이크로서비스에 다음 클래스를 추가한다.
@Configuration
@OpenAPIDefinition
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI(@Value() {
return new OpenAPI()
.servers(List.of(new Server().url("/")))
.components(new Components()
.addSecuritySchemes("bearerAuth",
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
.in(SecurityScheme.In.HEADER)
.name("Authorization")))
.info(new Info().title("User Service API")
.version("v0.0.1"))
.addSecurityItem(new SecurityRequirement().addList("bearerAuth"));
}
}
Authorize 버튼이 나타나게 하고 헤더에 토큰을 담아서 보내도록 하기 위해 .addSecuritySchemes()와 .addSecurityItem()을 호출한다.
openapi.service.url에는 gateway 주소를 넣어준다.
gateway에서는 따로 SwaggerConfig가 필요하지 않아서 이 부분은 생략한다.
spring:
main:
web-application-type: reactive
application:
name: gateway-service
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/v1/users/**, /api/v1/auth/**, /user-service/**
filters:
- RewritePath=/user-service/(?<segment>.*), /$\{segment}
설정을 살펴보면, predicates에 /user-service/** 를 추가하고, filters에서 RewritePath를 통해 요청 경로에서 /user-service/를 떼고 user service의 api-docs로 요청을 보내도록 한다. filters가 없으면 404 NOT FOUND가 발생할 것이다.
springdoc:
swagger-ui:
path: /swagger-ui/index.html
urls:
- name: user-service
url: /user-service/v3/api-docs
springdoc 관련 설정이다. path는 swagger로 접속할 경로를 지정하는 것이고, 아래에 각 서비스들의 api-docs 경로를 설정해주면 된다. 따로 설정하지 않으면 기본 경로가 /v3/api-docs이다.
현재 Gateway에서 filter를 통해 요청을 가로채 jwt 토큰을 파싱하고 헤더에 username, role을 넣어 각 서비스로 요청을 보내도록 하는 식으로 구현되어 있다.
if (path.equals("/api/v1/auth/login") || path.equals("/api/v1/auth/signup")
|| path.startsWith("/swagger-ui/") || path.startsWith("/v3/api-docs")) {
return chain.filter(exchange);
}
위 코드를 보면, 로그인 및 회원가입에는 필터를 수행하지 않고, path.startsWith("/swagger-ui/")와 path.startsWith("/v3/api-docs")에도 필터를 수행하지 않는 것을 볼 수 있다. 두 경로가 추가되어야 gateway에서 각 마이크로서비스의 swagger에 접근할 수 있다. 그렇지 않으면 401 에러가 발생한다.
구현이 잘 안되었던 부분인데 잘 참고합니다! 포스팅 잘 봤습니다!