[Swagger3] spring doc 2.1.0 설정 및 Map<String,Object> 스키마
swagger3는 SpringBoot3._버전에서 사용이 가능하고 SpringBoot2._ 버전에서는 사용이 불가능하다
SpringBoot2._ 버전에 적용할경우 아래 오류 발생.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'swaggerWebMvcConfigurer' defined in class path resource [org/springdoc/webmvc/ui/SwaggerConfig.class]: Unsatisfied dependency expressed through method 'swaggerWebMvcConfigurer' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'indexPageTransformer' defined in class path resource [org/springdoc/webmvc/ui/SwaggerConfig.class]: Unsatisfied dependency expressed through method 'indexPageTransformer' parameter 3; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'swaggerWelcome' defined in class path resource [org/springdoc/webmvc/ui/SwaggerConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springdoc.webmvc.ui.SwaggerWelcomeWebMvc]: Factory method 'swaggerWelcome' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/http/HttpStatusCode
build.gralde 파일에 다음 디펜던시를 추가한다.
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'
SwaggerConfig 클래스파일을 생성하고 설정한다.
@Configuration
public class SwaggerConfig {
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("springshop-public")
.pathsToMatch("/public/**")
.build();
}
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("springshop-admin")
.pathsToMatch("/swagger/**")
// .addOpenApiMethodFilter(method -> method.isAnnotationPresent())
.build();
}
@Bean
public OpenAPI api() {
return new OpenAPI()
.info(new Info().title("Spring Boot Open API TEST with swagger")
.description("Spring shop sample application")
.version("v0.0.1")
)
.components(new Components().addSchemas("CustomMapBody", customMapBody));
}
}
Swagger3에서는 Swagger2와 같이 BasePackage설정이 불가능하다.
따라서 아래와 같이 컨트롤러별로 설정해줘야한다.
@RestController
@RequestMapping("/swagger")
@Tag(name = "SwaggerTestController", description = "swaggerTestController")
public class SwaggerTestController {
@Operation(summary="Swagger 예제", description="Swagger의 기본 Annotation")
@GetMapping("/example2")
public String getSwaggerExam(@Parameter(name = "이름", required = true) @RequestParam String name) {
return name;
}
@Operation( description="Swagger의 기본 Annotation")
@GetMapping("/example3")
public String getSwaggerExam3(@Parameter(name = "이름", required = true) @RequestParam String name) {
return name;
}
}
ExampleValue 스키마 설정
Schema 객체를 생성해서 하나씩 주입해줘야 한다.
그리고 컨트롤러에서 해당 스키마 객체명을 참조한다.
@Operation(summary = "Dto 커맨드객체 Response 반환", description="Swagger 커맨드객체 반환 exampleValue 설정"
,responses = {
@ApiResponse(responseCode = "200", description = "가게 상세정보 조회 성공",content = @Content(schema = @Schema(implementation = SwagerTestDto.class))),
@ApiResponse(responseCode = "400")
})
@GetMapping("/example1")
public SwagerTestDto getSwaggerExam(@Parameter(name = "이름", required = true, schema = @Schema(ref = "#/components/schemas/CustomMapBody")) @RequestParam String name) {
return new SwagerTestDto();
}
Map<String, Object> 스키마
Map<String,Object> 스키마에 대한 설정이다
@Configuration
public class SwaggerConfig {
/* 빈등록 중략 */
@Bean
public OpenAPI api() {
Schema customMapBody = new Schema<Map<String, Object>>()
.addProperties("name",new StringSchema().example("John123"))
.addProperties("password",new StringSchema().example("P4SSW0RD"))
.addProperties("image",new StringSchema().example("https://robohash.org/John123.png"));
return new OpenAPI()
.info(new Info().title("Spring Boot Open API TEST with swagger")
.description("Spring shop sample application")
.version("v0.0.1")
)
.components(new Components().addSchemas("CustomMapBody", customMapBody));
}
}
new StringSchema 뿐만아니라 ObjectSchema도 등록할 수 있다.
아래는 컨트롤러의 메소드에 적용하는 코드이다
@Operation(summary = "Map 객체 Response 반환" , description="Swagger Map반환 exampleValue 설정")
@ApiResponses({
@ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(ref = "#/components/schemas/CustomMapBody")))
})
@PostMapping("/example1")
public Map<String,Object> getSwaggerExam2(@Parameter(name = "이름", required = true) @RequestParam Map<String,Object> name) {
return name;
}
@Operation 어노테이션의 responses 속성에 @ApiResponse를 선언하거나
@ApiResponses 어노테이션에 @ApiResponse를 선언하여 사용한다.
@ApiResponse의 content속성에 @Content어노테이션을 선언하고
해당 어노테이션의 schema속성에 @schema어노테이션을 선언한다.
@Schema어노테이션의 ref속성에 선언된 "#/components/schemas/CustomMapBody" 는
SwaggerConfig 클래스에서 등록한 OpenApi 빈에 components로 등록한 Schema를 참조하는것이다.