Springdoc OpenAPI UI
Springdoc OpenAPI UI๋ OpenAPI 3 ๊ธฐ๋ฐ์ Swagger API ๋ฌธ์๋ฅผ ์์ฑํ ์ ์๊ฒ ์ ๊ณตํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. ์ค๋์ Springdoc OpenAPI UI ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ํ์ตํด๋ณด๋ฉด์ ์๊ฒ๋ ์ ์ฉํ ์ ๋ณด๋ค ๋ํด์ ๊ณต์ ํด๋ณด๊ณ ์ ํ๋ค.
Select a definition ๊ธฐ๋ณธ ์ ํํ๊ธฐ
GroupeOpenAPI๋ฅผ ๋ฑ๋กํ์ฌ ํ๋๊ฐ ์๋ ๋ค์์ API ๊ทธ๋ฃน์ ์ ์ํ๊ณ ์ ํ ๋ springdoc.swagger-ui.urls-primary-name
์ ๊ธฐ๋ณธ์ผ๋ก ์ ํํ๊ณ ์ถ์ ๊ทธ๋ฃน ์ด๋ฆ์ ์
๋ ฅํ๋ฉด ๊ธฐ๋ณธ์ผ๋ก ์ ํ๋์ด์ง๋ค. ๊ทธ๋ฃน ํ์ ์์ ์ ๋ ฌ์ ์ํด ๊ธฐ๋ณธ๊ฐ์ด ๋จผ์ ๋
ธ์ถ๋์ง ์์ ๋ ์ ์ฉํ๋ค.
springdoc:
swagger-ui:
path: /swagger-ui.html
groups-order: desc
urls-primary-name: v1
์๋ฒ URL ์ง์ ๊ด๋ฆฌํ๊ธฐ
๊ธฐ๋ณธ์ผ๋ก ๋ง๋ค์ด์ฃผ๋ URL๋ก๋ ์ถฉ๋ถํ ์ ์์ง๋ง API ๋ฌธ์์ ๋ํ ์๋ฒ๋ฅผ ๋ณ๋๋ก ์ ๊ณตํ๊ณ ์ ํ๋ค๋ฉด ํธ์ถํ ์ ์๋ ์๋ํฌ์ธํธ๋ฅผ ๋ ธ์ถํด์ค ํ์๊ฐ ์๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ํด๋น ๊ธฐ๋ฅ์ ์ ๊ณตํด์ฃผ์ง ์๊ธฐ ๋๋ฌธ์ ์๋ฒ ์ฃผ์์ ๋ํ ConfigurationProperties๋ฅผ ๋ง๋ค๊ณ ์ฃผ์ ํ๋ฉด ๋๋ค.
springdoc:
server:
- url: /
description: Default
@Getter
@RequiredArgsConstructor
@ConstructorBinding
@ConfigurationProperties(prefix = "springdoc")
public class SpringdocServersProperties {
private final List<Server> servers;
}
@Bean
public OpenAPI openAPI(SpringdocServersProperties serversProperties) {
return new OpenAPI().servers(serversProperties.getServers());
}
๊ธฐ๋ณธ ์๋ต ๋ฉ์์ง ํ์ ๋นํ์ฑํ
์ค๋ฌด์์๋ GlobalOpenApiCustomizer ๋ฅผ ์ฌ์ฉํด์ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ ์๋ต ๋ฉ์์ง ์ค์์ ์ผ๋ถ์ ๋ํด์๋ง ํ์๋๋๋ก ํ๋๋ฐ ์คํ์ค๋ฒํ๋ก์ฐ์ ๋ต๋ณ์ ๋ณด๋ ๊ธฐ๋ณธ์ ์ผ๋ก @ControllerAdvice์ ์ํด ์ฐพ์์ฃผ์ด ์ถ๊ฐํด์ฃผ๋ ์๋ต ๋ฉ์์ง๋ฅผ ์ ์ธํ ์ ์๋ค.
springdoc:
override-with-generic-response: false
@Bean
public GlobalOpenApiCustomizer globalOpenApiCustomizer() {
return openapi -> openapi.getPaths().values()
.forEach(pathItem -> pathItem.readOperations()
.forEach(operation -> operation.getResponses()
.addApiResponse("500", new ApiResponse().description("Server Error")
.content(new Content().addMediaType("application/json", new MediaType())))));
}
Could not resolve pointer: /components/schemas/XXX does not exist in document
API ๊ทธ๋ฃน๋ง๋ค ๋ค๋ฅธ ์ธ์ฆ ๋ฐฉ์์ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ถ๋ฆฌํ๋ค๋ฉด ์๋์ ๊ฐ์ด .components ๋ฅผ ์ง์ ํ๋ ๊ฒ์ ์ฃผ์ํ๋๋ก ํด์ผํ๋ค. ์ธ์ฆ ์คํค๋ง ์ด์ธ์ ์์ฒญ๊ณผ ์๋ต์ ๋ํ ์คํค๋ง ํด๋์ค๊ฐ ํฌํจ๋์ง ์๊ธฐ ๋๋ฌธ์ .getComponents ๋ฅผ ์ด์ฉํ์ฌ ์ธ์ฆ ์คํค๋ง๋ฅผ ์ถ๊ฐํ์.
@Bean
public GroupedOpenApi apiV1() {
SecurityScheme bearerScheme = new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.in(SecurityScheme.In.HEADER)
.scheme("bearer")
.bearerFormat("JWT");
return GroupedOpenApi.builder()
.group("v1")
.pathsToMatch("/api/**")
.addOpenApiCustomiser(openapi -> openapi.info(info())
.addSecurityItem(new SecurityRequirement().addList(DEFAULT_AUTH))
//.components(new Components().addSecuritySchemes(DEFAULT_AUTH, bearerScheme)) // Resolve error!
.getComponents().addSecuritySchemes(DEFAULT_AUTH, bearerScheme)
)
.build();
}
์ด์ ๋ํ ์์ธํ ์ฝ๋๋ spring-boot2-springdoc ์์ ํ์ธํ ์ ์์ต๋๋ค.