[MSA스터디] 5. OpenAPI/스웨거를 사용한 API 문서화

vector13·2022년 10월 2일
0

RESTful 서비스에서 제공하는 API사용 편의성이 매우 중요 == 접근이 쉬운 좋은 문서가 있어야 유용하게 API를 사용할 수 있다.

스웨거는 restful 서비스를 문서화할 때 가장 일반적으로 사용하는 사양, 주요 api 게이트웨이 상당수가 스웨거를 기본 지원한다.

0. 기술요구사항

여전히 mac 기반이고 나는여전히 윈도우~^^ 😡

오늘 사용한 코드는
https://github.com/PacktPublishing/Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud/tree/master/Chapter05 에서 확인 가능

1. 스프링 폭스 소개

스프링 폭스를 사용하면 API를 구현하는 소스 코드와 연동해 API를 문서화가능

생각해보면 원래 프로젝트에서 api sheet 명세서를 사용했었는데 개발을 하다보면 수정이 잦아서 api 시트 수정을 자주했었다. 틀린 정보를 주면 프론트가 고생했던 경험이 몇 번 있다. ^^;; 🤯

  • 컴포넌트 의 인터페이스와 구현을 분리하는 것은 언제나 중요.
    - RESTful API의 문서화 관점에서--> API를 설명하는 자바 인터페이스를 문서에 추가!
    (not API를 구현하는 자바 클래스)

  • ❔누가 openapi 사양을 만들어주셨나요 천사님
    - ❕ 2015년, 스마트베어 소프트웨어가 리눅스 재단 산하의 OpenAPI 이니셔티브에 스웨거 사양을 기부하고 OpenAPI 사양을 만들었다.

책 에서는 스프링 폭스(=스웨거 기반의 문서를 런타임에 생성)이용해 api 문서 만든다.
스프링 폭스는 개발자가 설정한 구성 정보나 스프링 webflux, swagger annotation에서 얻은 구성 정보를 바탕으로 API 문서를 생성함

책 작성 당시에 v3가 개발중이었다고 한다. (지금은 v3나옴) -> 스프링 폭스 V3의 스냅샷 버전을 사용

소스코드 변경

그래들 빌드 파일에 의존성 추가

api 프로젝트와 product-composite-service 폴더의 build.gradle에 긱긱
implementation('io.springfox:springfox-swagger2:3.0.0') //chap5 -swagger
implementation('io.springfox:springfox-boot-starter:3.0.0') //chap5 -swagger 추가

ProductCompositeServiceApplication에 구성과 API 정보 추가

@EnableSwagger2WebFlux
public class Product CompositeServiceApplication {
	@Bean
	public Docket apiDocumentation() {
		return new Docket(SWAGGER_2)
				.select()
				.apis(basePackage("se.magnus.microservices.composite.product"))
				.paths(PathSelectors.any())
				.build()
				.globalResponseMessage(GET, emptylist())
				.apiInfo(new ApiInfo(
						apiTitle,
						apiDescription,
						05장 OpenAPI/스웨거를 사용한 API 문서화 187
				));
		apiVersion,
				apiTermsOfServiceUrl,
				new Contact(apiContactName, apiContactUrl, apiContactEmail),
				apilicense,
				apilicenseUrl,
				emptyList()
	}
  • @EnableSwagger2WebFlux : 스프링 폭스가 스프링 플럭스로 구현한 RESTful 서비스의 스웨거 V2 문서를 생성할 수 있도록 해주는 어노테이이션 , 애노테이션이 스프링 폭스를 초기화하는 시점

  • 스웨거 V2 문서를 생성하고자 Docket 빈을 초기화먼저 해주고

  • apis(), paths() 메서드 : 스프링 폭스가 API 정보를 찾을 위치를 지정 해주는 메소드
    • globalResponseMessage() : 스프링 폭스가 기본 HTTP 응답 코드(예: 401. 403)를 추가안해도 되게 해주는 메소드( 지금은 기본 응답 코드가 필요 없으므로)

@Value("${api.common.version}")
@Value("${api.common.title}")
@Value("${api.common.description}")
@Value("${api.common.termsOfServiceUrl}")
String apiVersion;
String apiTitle;
String apiDescription;
String apiTermsOfServiceUrl;
@Value("${api.common.license}") String apiLicense;
@Value("${api.common.licenseUrl}") String apiLicenseUrl;
@Value("${api.common.contact.name}") String apiContactName;
@Value("${api.common.contact.url}") String apiContactUrl;
@Value("${api.common.contact.email}") String apiContact Email;
  • api 변수로 Docket 빈을 구성. API 정보는 스프링의 @Value 애노테이션을 사용해 속성 파일에서 초기화.

ProductCompositeService에 API 정보 추가

@ApiOperation : API와 RESTful 오퍼레이션을 문서화하고자 API의 정보를 제공
@ApiResponse@ApiOperation : 오퍼레이션과 오류 응답을 설명
스프링 폭스는 @GetMapping 을 검사해 오퍼레이션의 입력 매개 변수와응답 유형을 알아서 파악해줌

package se.magnus.api.composite.product;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;


@Api(description = "REST API for composite product information.")
public interface ProductCompositeService {

    /**
     * Sample usage: curl $HOST:$PORT/product-composite/1
     *
     * @param productId
     * @return the composite product info, if found, else null
     */
    @ApiOperation(
        value = "${api.product-composite.get-composite-product.description}",
        notes = "${api.product-composite.get-composite-product.notes}")
    @ApiResponses(value = {
        @ApiResponse(code = 400, message = "Bad Request, invalid format of the request. See response message for more information."),
        @ApiResponse(code = 404, message = "Not found, the specified id does not exist."),
        @ApiResponse(code = 422, message = "Unprocessable entity, input parameters caused the processing to fails. See response message for more information.")
    })
    @GetMapping(
        value    = "/product-composite/{productId}",
        produces = "application/json")
    ProductAggregate getProduct(@PathVariable int productId);
}
  • @ApiOperation : 스웨거 어노테이션의 value 지정시 @Value가 아니라 속성 자리 표시자를 직접 사용 (스프링 폭스가 지원x 하기 때문) @ApiResponses 안의 오류 코드들 (예제에선 400, 404, 422) 설명을 자바 소스 코드에 직접 넣는다.

속성 파일에 API 설명 추가

@Value("${api.common.version}") String apiVersion;

같은 @Value 애노테이션 속성의 설명을 YAML 파일에 넣어야 하는데, 이를 yaml파일에서는

api:

  common:
    version: 1.0.0

이런 식이다.

먼저 스프링 폭스의 Docket 빈에 지정한 API에 대한 일반 정보를 입력하고, API 오퍼레이션의 자세한 설명을 넣는다

마이크로서비스 환경 구축 및 시작

도커 시작하고

cmd 열어서 실행시켜주고

http://localhost:8080/swagger-ui.html
swagger 페이지로 들어갔는데 Whitelabel Error Page가 뜬다.

일단은 저자 코드를 clone 한 chap05에서 build 해주고 docker up 해줬다.

여전히 안되는군..? ㅎ,ㅎ,,

저자의 깃허브의 issue에서 비슷한 문제는 아니지만 해결책의 실마리를 얻음
https://github.com/PacktPublishing/Hands-On-Microservices-with-Spring-Boot-and-Spring-Cloud/issues/8
http://localhost:8080/swagger-ui.html 가 아니라

http://localhost:8080/swagger-ui/index.html로 들어가서

드뎌 나왔다


1 : 오퍼레이션에 대한 한 줄 설명
2: 지원하는 입력 매개 변수 등 오퍼레이션을 자세히 설명하는 항목


-1 입력시 오류번호도 잘 나옴

정리 & 느낀점

이번 장에서는 OpenAPI/스웨거를 사용한 API 문서화방법과 마이크로서비스 환경에서 공개된 api 를 OpenAPI/스웨거를 사용해 빠르게 문서화하는 방법을 공부했다.

spring fox(== annotation으로 openApi 및 swagger 기반의 api 문서 생성해주는 tool) 로 공개 api 문서화 위해서는 소스코드 수정하고, 문서화 방법을 살펴봤다.
swagger documentation에 내장된 swagger viewer(==swagger UI) 를 사용해 웹 브라우저에서 documentation에 점검 (==시각화) 및 API 시험 (== 테스트) 방법도 살펴봤다.

swagger 를 사용해볼 수 있어서 좋았으나 우리 프로젝트에서 보내는거랑 조금 다르게 api가 구성되어있어서 현재 우리가 겪고있는 swagger문제를 해결할 방법은 다시찾아보긴 해야할 것 같다. 대신에 openApi를 이용해 api spec 빠른 명세를 하는 것의 이론적 바탕이나 이유(장점)을 명확히 알게돼서 좋았다. ◜◡◝

profile
HelloWorld! 같은 실수를 반복하지 말기위해 적어두자..

0개의 댓글