스프링 부트

[SpringBoot] OpenAPI 3.0 추가 구성 해보기! (swagger-ui)

h__hj 2023. 1. 15. 00:03

# OpenAPI 3.0 example code - 3 (swagger-ui)

https://hjho95.tistory.com/39 는 OpenAPI를 사용하기 위한 설정.

https://hjho95.tistory.com/40 은 Annotation을 이용한 Document작성.

https://hjho95.tistory.com/41 은 ApiResponse의 ref 구현.

 

이번에 쓸 내용은 @ApiResponse에 ref 는 뭔가 찾아보고,, 확인하고,,, 설정하고,,,근데 그냥 내가 해봄..

구현한 내용이 올바르지 않은 구현 일수 있음... 도큐먼트를 찾아봐도 쉽게 설정할수 있는 샘플코드가 없으니 뭐ㅏ,,ㅠ

# Refference

document: https://springdoc.org

example-ui: http://158.101.191.70:8081/swagger-ui/index.html

github: https://github.com/springdoc/springdoc-openapi-demos/blob/master/springdoc-openapi-spring-boot-2-webmvc/src/main/java/org/springdoc/demo/app2/Application.java

# 환경

Tool  : STS 4.13.0
Ver   : 2.7.5 [GA]
JDK   : 11
Repo  : MAVEN
DB    : ORACLE XE (11g), PostgreSQL (14)
View  : Thymeleaf
jQuery: 3.6.0

@Operation > @ApiResponses ref 설정

@Tag(name = "Data", description = "데이터베이스 조회 API")
@RestController
@RequestMapping("/api-v1/common/data")
public class DataController {
    
    @Operation(tags = { "Data" }, 
               summary = "오라클 데이터베이스 조회", 
               description = "Read to Oracle database",
               parameters = {
                       @Parameter(name = "name", description = "테스트 입력 파라미터", example = "오라클", required = true)
               },
               responses = {
                       @ApiResponse(responseCode="200"),
                       @ApiResponse(responseCode="500", content = @Content),
                       @ApiResponse(responseCode="0000", ref="success"),
                       @ApiResponse(responseCode="9999", ref="error"),
               }
    )
    @GetMapping("/oracle")
    public RestResponse oracle(@RequestParam String name){
        Map<String, Object> data = oracleService.oracle(name);
        
        RestResponse response = new RestResponse();
        response.setOk();
        response.setData(data);
        return response;

    }
}

ref 설정된 document

# 설명

 @ApiReponse를 작성하던 중 ref의 필드를 보고 @ApiReponse를 @Schema 처럼 Component에 등록할 수 있겠구나!

싶어서 여러가지 방법으로 작성해보았는데,,, 

우선 @Schema 처럼 VO Class위에 @Schema 대신 @ApiResponse를 등록해보았다. >>> 안됨.

Controller 위에 ApiResponses를 등록해두고 name 설정으로 해보았다. >>> 안됨.

그 외 여러가지로 시도해 보았으나 등록이 안되었다. 

확인은 "/v3/api-docs" 로 들어가면 json이 나오는데 components 아래 schemas와 responses가 있다. responses에 등록이 되면 ref로 쓸 수 있을 것 같았다. >> 그래서 만듬.

 

무엇이든 간에 객체는 Componets > Responses(ApiResponse)이기 때문에 찾아봄.

# Configuration

@Configuration
public class OpenApiConfig {    
    @Bean
    public OpenAPI openAPI() {
        Components components = new Components();
        components.addResponses("success", new ResponseSuccess());
        components.addResponses("error"  , new ResponseError());
        
        return new OpenAPI()
                  .info(
                          new Info().title("[Dev] Document (blog-api)")
                                  .description("블로그 API 서버 문서")
                                  .version("1.0.0")
                                  .license(new License().name("Apache 2.0").url("http://springdoc.org"))
                  )
                  .externalDocs(
                          new ExternalDocumentation()
                                  .description("Github")
                                  .url("https://github.com/springdoc/springdoc-openapi-demos/blob/master/springdoc-openapi-spring-boot-2-webmvc/src/main/java/org/springdoc/demo/app2/Application.java")
                  )
                  .components(components);
    }
}

OpenAPI 객체에 components를 설정할 수 있는 메소드가 있었다. 

Components의 Responses는 ApiResponse 클래스만 들어갈 수 있음. >>> 그래서 ApiResponse를 상속받은 Class를 만듬.

public class ResponseSuccess extends ApiResponse {

    public ResponseSuccess() {
        super.setDescription("Response Body Success Code");
        
        Schema<RestResponse> schema = new Schema<RestResponse>();
        schema.example("{\"code\":\"0000\",\"message\":\"정상적으로 처리 되었습니다.\",\"data\":\"Object\",\"success\": true}");
        
        MediaType mediaType = new MediaType();
        mediaType.schema(schema);
        
        Content content = new Content();
        content.addMediaType("application/json", mediaType);
        
        super.setContent(content);
    }
}

@ApiResponse > @Content > @MediaType > @Schema 로 이루어져 있으니, 생성자로 해당 내용을 초기화 시켜준다. 

그 후 OpenApiConfig의 key를 "success" 로 등록해주면 

/v3/api-docs 의 json string

Swagger의 설정 json 내용에 들어간 걸 볼 수 있다. 

그러면 @Operation > @ApiResponses ref 설정은 등록한 key인 success나 error을 넣어주면 ref 설정된 document 이미지 처럼 나오게 된다. 

기본적인 Http Status 코드 들은 responseCode에 등록하게 되면 components > responses는 없지만 기본적으로 등록이 되어있다. (200-OK, 500-Internal Server Error) 응답은 자동적으로 메소드의 Return 객체이다.

 

이처럼 ApiResponse를 등록해두면 자주 사용하는 응답코드를 작성해두면 쉽게 표현할 수 있어보인다. (크게 쓸모는 없어보이지만 있으면 좋을만한,,,,)

 

# 전체적인 내용

 이렇게 OpenAPI에 대하여 1, 2, 3을 작성해보았다,,,

원래는 간단하게 하려했으나 찾으면 찾을 수록 재밌는게 나오고 한번 하는거 제대로 설정해보고 싶었다. 

블로그에서 작성한 내용 외에는 Authorizations 에 대한 설정도 있는데 내용이 너어무 방대하고 나도 아직 제대로 설정, 테스트 해보질않아 놔두고 있다,,, 근데 난 블로그에 쓰진 않겠지만 테스트 해볼 예정.

 

짬나는 시간으로 Document를 찾고, OpenApi를 설정하고, 테스트하고, 이것 저것 다 확인해보다가 한달이 흐른 듯,,, (한달동안 한건 아니고,, 12월 약속이 많아 자주 못했음)

Swagger는 단위 테스트하기 정말 좋은 라이브러리인 것 같아 정성스럽게 블로그를 작성했다.

 

이상 OpenAPI는 끝.