Spring Boot Application에 대한 Http Api Document를 Redocly UI로 생성하기 위해 작성한 문서입니다.
OpenApi는 Http Api Document에 대한 표준입니다. 이러한 표준이 존재하기 때문에 Swagger-UI, Redocly 등등 여러 Http Api Document UI 라이브러리는 OpenApi를 기반으로 UI를 생성해줍니다. 즉 Http Api Document를 OpenApi 형식에 맞게 만든다면 위와 같은 라이브러리로 Http Api Document에 대한 UI는 쉽게 교체가 가능해집니다.
springdoc-openapi는 Spring Boot에서 OpenApi 스펙에 맞게 Http Api Document를 자동으로 생성해주는 라이브러리 입니다. Swagger-Core 기반으로 되어있기 때문에 Swagger Annotation을 이용해서 Http Api Document을 작성합니다.
아래 이미지는 Springdoc-openapi Modules에 대한 구조입니다.
출처 : https://springdoc.org/#spring-webmvc-support
Spring Boot 3.1.4와 Spring-Web-Mvc 기준으로 작성하고있습니다.
plugin {
id 'org.springdoc.openapi-gradle-plugin' version "1.7.0"
...
}
dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.2.0'
implementation 'org.yaml:snakeyaml:2.2'
...
}
OpenApi파일을 생성하기 위한 org.springdoc.openapi-gradle-plugin을 설정해주고 현재 프로젝트가 spring web mvc기반이고 Swagger UI 대신 Redocly UI를 사용할 것이기 때문에 springdoc-openapi-starter-webmvc-api 의존성을 추가해줍니다. springdoc-openapi-starter-webmvc-api는 snakeyaml 라이브러리에 대한 의존성을 가지고 있습니다. springdoc-openapi-starter-webmvc-api:2.2.0 버전에서는 snakeyaml:1.33 버전을 사용하고 있는데 해당 라이브러리 버전은 취약점이 있기 떄문에 org.yaml:snakeyaml:2.2 의존성을 따로 추가해 주었습니다.
Spring Doc Properties 설정은 https://springdoc.org/#properties 링크에서 Springdoc-openapi Properties 섹션에서 자세하게 볼 수 있습니다. OpenApi를 별도의 html로 만들것이기 때문에 api-docs는 사용하지 않습니다. 그래서 아래와 같이 application.yaml 파일에서 api-docs를 disable 설정해주었습니다.(Default는 enable)
springdoc:
api-docs:
enabled: false
하지만 enabled false를 하게 되면 openapi 문서에 대한 api가 비활성화 되기 때문에 문서를 생성하지 못합니다. 그렇기 때문에 Gradle Script에 Custom한 설정을 필요한데 generateOpenApiDocs gradle Task를 실행할 때 springdoc.api-docs.enabled=true 설정 해주어야합니다. 아래와 같이 설정해주면 됩니다.
openApi{
customBootRun {
args.set(["--springdoc.api-docs.enabled=true"])
}
}
필수 설정은 아니지만 OpenApi에 대한 Title, Version, Description 등등 Meta Data들을 설정해주기 위해 아래와 같이 OpenAPI에 대한 빈을 생성하고 등록해줍니다.
@Configuration
public class OpenAPIConfig {
@Bean
public OpenAPI openAPI() {
Info info = new Info()
.title("데모 프로젝트 API Document")
.version("v0.0.1")
.description("데모 프로젝트의 API 명세서입니다.");
return new OpenAPI()
.components(new Components())
.info(info);
}
}
문서가 제대로 생성이 되는지 확인하기 위해 간단하게 Swagger의 Tag 어노테이션만 있는 TestController를 생성해주겠습니다.
@Tag(name = "test",description = "It is test")
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping
public String test(){
return "Test";
}
}
cd project-path
./gradlew clean generateOpenApiDocs
위 명령어를 실행하게 되면 openapi.json 파일이 project/build 폴더에 생성됩니다.
OpenApi 파일은 이미 생성되어있기 때문에 해당 파일을 redocly 명령어로 빌드만 하면 되기 떄문에 redocly/cli 이미지와 아래 도커 명렁어를 통해 생성할 수 있습니다.
docker pull redocly/cli
docker run -v project-path/build:/app -w /app redocly/cli build-docs /app/openapi.json
생성되어있는 OpenApi 파일을 이용해서 Redocly Html 파일을 생성할 것이기 때문에 spring boot project의 build 폴더를 컨테이너의 작업환경인 /app 폴더로 볼륨 마운트 설정을 해줍니다. 그리고 Redocly의 명령어인 build-docs 를 통해 redocly html을 /app 경로에 생성해줍니다. 볼륨 마운트 설정을 해주었기때문에 project의 build 폴더에 redoc-static.html 파일이 생성됩니다.
전체 스크립트
./gradlew clean generateOpenApiDocs
# 이미지 조회
if docker images -q "redocly/cli" > /dev/null; then
echo "redocly/cli image exists:"
else
docker pull redocly/cli
echo "redocly/cli image does not exist:"
fi
echo "redocly.html 생성중"
docker run -v ./build:/app -w /app redocly/cli build-docs /app/openapi.json
echo "redocly.html 생성"
rm ./build/openapi.json
echo "openapi.json 삭제"
LGTM