# OpenAPI 3.0 example code - 2 (swagger-ui)
이전 설정인 https://hjho95.tistory.com/39 에서 OpenAPI에 대한 pom.xml, application.yml, Configuration을 작성하여 기동해보는 걸 해보았다.
이번에는 Document 내에 들어가는 해당 API의 설명, 정의 등 작성해보는 시간이다.
https://hjho95.tistory.com/39 는 OpenAPI를 사용하기 위한 설정.
https://hjho95.tistory.com/40 은 Annotation을 이용한 Document작성.
https://hjho95.tistory.com/41 은 ApiResponse의 ref 구현.
# Refference
document: https://springdoc.org
example-ui: http://158.101.191.70:8081/swagger-ui/index.html
# 환경
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
# 기본 페이지 (DrinksController)
@RestController
@RequestMapping("/api-v1/drinks")
public class DrinksController {
@GetMapping
public RestResponse listDrinks(@ModelAttribute DrinksPVO drinks) {
RestResponse response = new RestResponse();
List<DrinksRVO> listDrinks = new ArrayList<DrinksRVO>();
response.setOk();
response.setData(listDrinks);
return response;
}
@GetMapping("/{drinksNo}") ,,,생략
@PostMapping ,,,생략
@PutMapping ,,,생략
@DeleteMapping("/{drinksNo}") ,,,생략
}
dringks-controller는 DrinksController.java 파일에 정의된 URL이다. 아무것도 작성하지 않은 일반 Controller도 그냥 알아서 잘해준다,,, 이 정도면 그냥 혼자 api 단위 테스트를 할 수 잇을 정도는 되는 듯,,,!
# 어노테이션 작성 페이지 (DataController)
1. @GetMapping & @RequestParam & application/x-www-form-urlencoded & String
@Tag(name = "Data", description = "데이터베이스 조회 API")
@RestController
@RequestMapping("/api-v1/common/data")
public class DataController {
@Autowired
private OracleService oracleService;
@Autowired
private PostgreService postgreService;
@Operation(tags = { "Data" },
summary = "오라클 데이터베이스 조회",
description = "Read to Oracle database",
parameters = {
@Parameter(name = "name", description = "테스트 입력 파라미터", example = "오라클", required = true)
},
responses = {
@ApiResponse(responseCode="200", description = "OK [Response Data Schema: Map]", content =
@Content(mediaType = "application/json", schema =
@Schema(example = "{\"code\": \"0000\", \"message\": \"정상적으로 처리 되었습니다.\", \"data\": {\"INPUT_NAME\": \"parameters[name]\",\"DATABASE_ID\": \"Oracle\",\"NOW_TIME\": \"2023-01-14 17:59:10\"},\"success\": true}")
)
),
@ApiResponse(responseCode="0000", ref="success"),
@ApiResponse(responseCode="9999", ref="error"),
@ApiResponse(responseCode="9001", description = "입력 값이 존재하지 않습니다.", content = @Content),
@ApiResponse(responseCode="9004", description = "토큰이 만료되었습니다.", content = @Content),
}
)
@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;
}
}
1. 설명
@Tag
Contoller class 단위의 붙이는 어노테이션.
메소드(url)들을 name으로 그룹핑, description으로 설명을 적어준다.
@Operation
메소드 단위에 붙이는 어노테이션.
tags는 @Tag의 name으로 그룹 설정한다. (여러개 가능).
summary는 바로 보이는 설명, description은 열면 보이는 설명을 작성할 수 있다.
parameters 는 @Parameter 를 이용하여 name 파라미터의 필수여부(required), 예제입력(example), 설명(description)을 작성할 수 있다.
responses는 @ApiResponse을 이용하여 각각의 응답 내용을 정의 할 수 있다. responses 중 @ApiResponse responseCode가 같은 값이 여러개일 경우, 마지막에 설정한 값으로 표시된다.
차근차근보면 어노테이션이 @ApiResponse → @Content → @Shcema 로 정의가 되는데 아래에서 부터 보면
@Shcema는 VO 단위.
@Content는 해당 VO가 무슨 ContentType(mediaType)인지 정의.
@ApiResponse로 그 VO가 어떤 코드(responseCode)일 경우 응답이 나가는지와 설명(description)을 적어준다고 보면 된다.
@Content 내 입력이 없으면 @ApiResponse의 code, description만 보여진다. 특정 에러코드일 때의 메시지를 보여주면 좋을 것 같아 작성해보았다.
@Operation 아래 responses가 아니라 @ApiResponses 를 따로 어노테이션을 걸고 @ApiResponse를 작성해도 된다.
2. @PostMapping & @RequestBody & application/json & Map
@Operation(tags = { "Data" },
summary = "포스트그레SQL 데이터베이스 조회",
description = "Read to PostgreSQL database",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Input Schema: Map<String, String>", content = {
@Content(mediaType = "application/json", schema =
@Schema(example = "{\"text\":\"포스트그레SQL\"}"))})
)
@PostMapping("/postgre")
public RestResponse postgre(@RequestBody Map<String, String> input){
Map<String, Object> data = postgreService.postgre(MapUtils.getString(input, "text", ""));
RestResponse response = new RestResponse();
response.setOk();
response.setData(data);
return response;
}
2. 설명
그냥 하는 건 어렵지 않다. 하지만 점점 응용하는 게 복잡해진다.
@RequestParam은 그냥 paramters로 정의하면 되는 데 API는 보통 json이다. 거기에 정의되지 않은 Map이라면 key 자동으로 "additionalProp1" 으로 입력 되어있다.
responseBody는 @ResponseBody(패키지루트가 다름) 로 정의 할 수 있는데, @Schema 로 VO단위인 Map의 기본 입력값을 설정해주면 자동으로 예제와 같이 text가 key로 입력 되고 포스트그레SQL이 입력값으로 매핑되어있다.
3. @PostMapping & @RequestBody & application/json & VO(Schema)
@PostMapping("/twice1")
public RestResponse twice1(@RequestBody DataPVO dataPVO){
Map<String, Object> data = oracleService.twice(dataPVO.getText());
RestResponse response = new RestResponse();
response.setOk();
response.setData(data);
return response;
}
@Schema(description = "데이터베이스 조회 파라미터")
@Data
public class DataPVO {
@Schema(title = "문자", description = "입력 파라미터가 input_name으로 리턴", format = "YYYY-MM-DD HH24:MI:SS", requiredMode = RequiredMode.REQUIRED, minLength = 1, maxLength = 30, example = "오라클과 포스트그레SQL", defaultValue = "oracle and postgreSQL")
private String text;
@Schema(title = "여부", description = "여부", requiredMode = RequiredMode.NOT_REQUIRED)
private String yn;
@Schema(hidden = true)
private String hidden;
}
3. 설명
기본적인 케이스라고 볼수 있다.
@Schema 어노테이션을 등록한 VO는 Swagger의 Schemas Component에 등록된다.
등록되면 @Content > @Schemas > ref 로 등록한 VO를 참조할 수 있다.
Class단위에 @Schema를 붙이면 해당 클래스가 Schema로 등록이 되고, Field 단위로 등록이 되면 해당 필드에 대한 정의를 작성할 수 있다.
필드 단위의 @Schema를 보면, title로 필드명, maxLength/minLength로 길이제한, format으로 값이 어떤 형식인지, requiredMode로 필수값인지 아닌지, description으로 설명, hidden으로 Schema의 표시 여부, example로 자동입력값을 작성할 수 있다. 정의한다고 try it out 시 적용되는게 아니라 단지 Document성으로 필드에 대한 정보를 정의한다고 볼 수 있다.
4. @PostMapping & @ModelAttribute & application/x-www-form-urlencoded & VO(Schema)
@Operation(tags = { "Data" },
summary = "오라클과 포스트그레SQL 데이터베이스 조회",
description = "Read to Oracle and PostgreSQL database",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "json 형식이 아닌 form 형식",
content = @Content(mediaType = "application/x-www-form-urlencoded", schema = @Schema(ref = "DataPVO")))
)
@PostMapping("/twice2")
public RestResponse twice2(@ModelAttribute DataPVO dataPVO){
Map<String, Object> data = oracleService.twice(dataPVO.getText());
RestResponse response = new RestResponse();
response.setOk();
response.setData(data);
return response;
}
4. 설명
설정 찾는게 힘들었다. 코드보면 이해가 쉽지만, swagger가 자동으로 ModelAttribute를 인식하여 설정되지 않았다.
VO를 사용하는데 application/x-form-urlencoded 방식이라면 responseBody 설정에서 @Content의 mediaType을 설정해주어야 Swagger가 위와 같이 만들어준다. @Schema는 ref를 이용해 DataPVO를 등록해준다.
# 전체적인 내용
일단 하고싶은 건 다 해본 듯 하다. 특정 상황, 특정 타입 별로 확인해보고, Document의 표시 될 수 있는가가 제일 중요했다.
추가로 @ApiResponse ref 에 대해서 3 편에서 해볼 생각이다.
https://hjho95.tistory.com/41 은 ApiResponse의 ref 구현.
'스프링 부트' 카테고리의 다른 글
[SpringBoot] 요청부터 응답까지! 프로세스 흐름도 (0) | 2023.01.15 |
---|---|
[SpringBoot] OpenAPI 3.0 추가 구성 해보기! (swagger-ui) (0) | 2023.01.15 |
[SpringBoot] OpenAPI 3.0 설정하기! (swagger-ui) (0) | 2023.01.14 |
[SpringBoot] RestTemplate 구성하기! (0) | 2022.11.27 |
[SpringBoot] RestTemplate - exchange (POST, PUT, DELETE) 로 통신하기! (1) | 2022.11.19 |