MSA에서의 swagger 적용

진병욱·2023년 11월 23일

Spring Cloud MSA 적용

목록 보기
1/3
post-thumbnail

MSA에서 API Document를 손쉽게 사용해보자!!

MSA로 백엔드 환경을 구축하면서, 기존처럼 각 서비스마다 Swagger를 설정하고 이를 개별로 확인하는 것은 비효율적이다.

하지만 이를 간단하게 gateway에 swagger를 적용함으로서, 해결이 가능하다!!

현재 프로젝트에서의 적용된 백엔드 환경은 아래처럼 구성했다.

  • Java 17
  • spring boot 3.1.5
  • gradle
  • yaml


Spring Cloud Gateway

일단 Spring Cloud gateway에서의 설정법부터 알아보자
의존성설정만 추가하면 된다!!

의존성 추가 (gradle)

https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webflux-ui

위의 링크에서 최신 버전의 의존성 확인이 가능하다. 필자는 project 당시 최신 버전인 2.2.0을 사용하였다.

implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webflux-ui', version: '2.2.0'

여기서 webflux란?

  • spring 5.0부터 추가된 것으로, 간단하게 말하면 기존의 MVC는 요청과 쓰레드가 1:1이었다면, webflux는 요청과 쓰레드가 N:1이다. 따라서 요청에 따른 쓰레드 관리가 용이하다는 장점이 있다.

설정 추가 (yaml)

swagger에서의 마이크로서비스와의 매칭해주는 작업이다.

springdoc:
  swagger-ui:
    urls[0]:
      name: 인증 서비스
      url: http://게이트웨이 주소/api/auth/v3/api-docs
    urls[1]:
      name: 회원 서비스
      url: http://게이트웨이 주소/api/user/v3/api-docs
    urls[2]:
      name: 랭크 서비스
      url: http://게이트웨이 주소/api/rank/v3/api-docs
    urls[3]:
      name: 메일 서비스
      url: http://게이트웨이 주소/api/mail/v3/api-docs
    urls[4]:
      name: 게임 서비스
      url: http://게이트웨이 주소/api/game/v3/api-docs
    urls[5]:
      name: 결제 서비스
      url: http://게이트웨이 주소/api/payments/v3/api-docs
    urls[6]:
      name: 공지 서비스
      url: http://게이트웨이 주소/api/notice/v3/api-docs

설정에 대해서 잠깐 설명을 덧붙이자면,

이 사진에서의 definition을 설정하는 작업이다.
그래서 서비스를 클릭하면, 해당 서비스의 api-docs를 불러와 API 문서를 보여주는 방식이다.

해당 서비스에서는 /api/<서비스명>을 제외하고 받을 것이기 때문에
게이트웨이에서 prefix를 제거하여 서비스로 요청을 전달해주면 된다.

(혹은 각 서비스의 api-docs url을 /api/auth/v3/api-docs와 같이 설정을 해 주어도 된다 => 이렇게 하면 아래의 설정을 추가로 할 필요는 없다)

        - id: payments-service
          uri: lb://PAYMENTS-SERVICE
          predicates:
            - Path=/api/payments/v3/api-docs/**
            - Method=GET
          filters:
            - RewritePath=/api/payments/(?<path>.*), /$\{path}

여기까지 하면 게이트웨이에서의 swagger 설정은 끝이지만,
편의를 위해 게이트웨이에 접속했을 때, 바로 swagger로 접속하도록 아래와 같은 설정을 추가 해 준다.

springdoc:
  swagger-ui:
    use-root-path: true

위 설정을 마치면, gateway로 웹 접속을 하면 자동으로 swagger로 이동한다.
여끼가지 설정을 마친다면, gateway는 끝이다.
이젠 서비스에 swagger 설정만 하면 끝!!



마이크로서비스

마이크로서비스에서도 gateway에와 비슷하게 설정을 하면 된다.

의존성 추가 (gradle)

각 서비스에서도 gateway에서 설정했던 것처럼 springdoc을 추가해 준다.

implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.2.0'

설정 추가 (yaml)

springdoc:
  api-docs:
    version: openapi_3_1
    enabled: true
    #path: /api/mail/v3/api-docs 
    # 게이트웨이 라우팅에서 prefix를 제거하지 않았다면 해당 설정을 추가
  enable-spring-security: true
  default-consumes-media-type: application/json
  default-produces-media-type: application/json

설정에 대한 설명을 덧붙이자면, api-docs 버전 및 사용 여부에 대한 설정과 spring security와 타입에 대한 설정이다.

path 부분은 현재는 comment 처리하였지만, 위에서 prefix제거 작업을 하지 않았다면 이 부분을 해제하고 mail 부분은 해당 서비스의 이름으로 변경해주면 된다.

swagger 설정 예시

@RequiredArgsConstructor
@Configuration
@OpenAPIDefinition(
        info = @Info(title = "API Document", description = "MAIL SERVICE 명세서", version = "v3")
)
public class SwaggerConfig {

    @Bean
    public OpenAPI openAPI() {

        return new OpenAPI()
                .addServersItem(new Server().url("/"));
    }

}

SwaggerConfig라는 클래스를 만들고, annotation으로 설정을 추가했다.
@OpenAPIDefinition annotation으로 document의 이름을 설정한다.

여기서 서버의 url을 /로 설정하는 것은 해당 서버를 배포하였을 때,
서버가 https로 설정되어 있을 경우에 swagger를 통해 API 요청시에,

http, https 간의 통신에서 cors와 같은 문제가 발생할 수 있어서,
url을 root 경로로 설정해서 이를 방지하기 위함이다.

만약 여기서 해당 서비스가 로그인을 필요로 한다면 아래 내용을 서비스 별로 swagger 설정 파일에 추가하면 된다.

일반적으로 Swagger를 통한 요청은, 클라이언트에서 요청하는 것과 똑같기 때문에
로그인이 필요한 경우는, 추가 설정을 해주어야 한다.

JWT를 포함하여 요청을 보내도록 설정이 필요하다.

@Bean
public OpenAPI openAPI() {
    SecurityScheme securityScheme = new SecurityScheme()
            .type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
            .in(SecurityScheme.In.HEADER).name("Authorization");
    SecurityRequirement securityRequirement = new SecurityRequirement().addList("bearerAuth");

    return new OpenAPI()
            .components(new Components().addSecuritySchemes("bearerAuth", securityScheme))
            .security(Arrays.asList(securityRequirement))
            .addServersItem(new Server().url("/"));
    }

코드에 대한 설명을 덧붙이면, 클라이언트의 프론트단에서 유저 요청시에 로그인 유저의 경우 header에 토큰을 추가하여 요청을 보내는 작업이 있는데
이와 똑같다고 생각을 하면 된다.



최종 확인!!

스웨거 이미지

Select a definition에서 각 마이크로서비스의 접근이 가능하다.
또한 회원 관련 처리를 위한 Authorize 버튼이 추가된 것도 확인이 가능한다.

해당 버튼을 클릭하여 JWT를 넣어주면, 모든 요청을 보낼 때 헤더에 토큰을 넣어서 요청을 보내
회원 관련된 요청도 가능하다.

profile
새로운 기술을 접하는 것에 망설임이 없고, 부족한 것이 있다면 항상 배우고자 하는 열정을 가지고 있습니다!

0개의 댓글