Swagger3으로 변경하면서 이전에 output의 클래스를 지정하는 기능이 작동하지 않았다.
예를들면 다음과 같다.
Swagger2 버전에서의 설정
@ApiOperation(value = "1. 로그인")
@ApiResponses(
@ApiResponse(code = 200, message = "success", response = ResponseLogin.class)
)
@PostMapping("/api/oauth/login")
public ResponseNoCount login(@RequestBody @Valid RequestLogin request) {
ResponseLogin response = new ResponseLogin("aaa","Bbb",10, false);
return new ResponseNoCount(response);
}
ResponseLogin.java
@Getter
public class ResponseLogin {
@ApiModelProperty(value = "accessToken")
private String accessToken;
@ApiModelProperty(value = "refreshToken")
private String refreshToken;
@ApiModelProperty(value = "expiresIn(만료, 초단위)")
private int expiresIn;
@ApiModelProperty(value = "가입여부")
private Boolean memberYn;
}
Swagger2 에선 이렇게 하면 다음처럼 잘 작동되었다.
문제는 3버전으로 오면서 다음처럼 수정을 했는데, 에러가 발생하면서 (no example avaliable) 이라고 뜨고 있었다.
변경된 설정
@Operation(tags = "1. 로그인", summary = "로그인",
responses = {
@ApiResponse(
responseCode = "200", description = "ok"
, content = @Content(schema = @Schema(implementation = ResponseLogin.class)))
})
@PostMapping("/api/oauth/login")
public ResponseNoCount login(@RequestBody @Valid RequestLogin request) {
ResponseLogin response = new ResponseLogin("aaa","Bbb",10, false);
return new ResponseNoCount(response);
}
ResponseLogin.java 변경 (@ApiModelProperty => @Schema 로 변경)
@Schema(description = "로그인 요청")
@Getter
public class ResponseLogin {
@Schema(description = "accessToken")
private String accessToken;
@Schema(description = "refreshToken")
private String refreshToken;
@Schema(description = "expiresIn(만료, 초단위)")
private int expiresIn;
@Schema(description = "가입여부")
private Boolean memberYn;
}
에러문구
Swagger-ui 화면
그래서 api-docs 에서 생성된 json을 보니 다음과 같이 Error-ModelName 이라고 되어있다.
해당 상황은 다음과 같은 설정에서 문제가 발생하는데 output을 그대로 담는게 아니라 어떤 특정 폼을 담아서 리턴할때 그렇게 발생한다. 위 코드에서 ResponseNoCount 에대한 클래스를 공개하지 않았는데 해당 구성은 다음과 같다.
@Getter
public class ResponseNoCount<T> {
private T values;
public ResponseNoCount(T values) {
this.values = values;
}
}
즉 ResponseNoCount 클래스에서 제너릭으로 output으로 보낼 객체를 받은다음(여기서는 ResponseLogin.java) 리턴하게 되어있는데, 이것을 사용하지 않고 ResponseLogin 를 그대로 리턴하면 이런 문제가 발생하지 않는다.
@Operation(tags = "1. 로그인", summary = "로그인",
responses = {
@ApiResponse(
responseCode = "200", description = "ok"
, content = @Content(schema = @Schema(implementation = ResponseLogin.class)))
})
@PostMapping("/api/oauth/login")
public ResponseLogin login(@RequestBody @Valid RequestLogin request) {
ResponseLogin response = new ResponseLogin("aaa","Bbb",10, false);
return response;
}
그런데 이미 만들어진 것을 모두 이렇게 바꿀 순 없는 노릇이었다. 그리고 ResponseNoCount.java 에는 최소한의 정보만 담겨있지만 그 외 데이터를 추가해도 form을 유지해서 사용하기 좋으며 frontend와의 협업에도 도움이 된다. 그럼 이 문제를 어떻게 해결해야 할까 고민하다 차선책이지만 방법을 찾았다.
Error-ModelName 이 발생하는 이유는 말그대로 모델을 생성하지 못해서 그렇다. 지금까지 찾아본 바로 모델을 생성하는 방법은 2가지가 있다.
1) 방금전처럼 return 을 즉각 던질경우
2) 지정한 클래스의 모델이 생성되도록 이전 버전의 @ApiResponse을 같이 등록하기
그러나 1번은 output form을 유지해야 한다는 점에서 불가하니 2번 방법을 사용하기로 했다.
수정된 방법은 다음과 같다.
@Operation(tags = "1. 로그인", summary = "로그인",
responses = {
@ApiResponse(
responseCode = "200", description = "ok"
, content = @Content(schema = @Schema(implementation = ResponseLogin.class)))
})
@io.swagger.annotations.ApiResponses(
@io.swagger.annotations.ApiResponse(
response = ResponseLogin.class, message = "ok", code=200)
)
@PostMapping("/api/oauth/login")
public ResponseNoCount login(@RequestBody @Valid RequestLogin request) {
ResponseLogin response = new ResponseLogin("aaa","Bbb",10, false);
return new ResponseNoCount(response);
}
이렇게 하면 Error-ModelName 이라든가 Could not resolve reference: undefined 에러가 사라진다.
뭔가 찜찜하게 끝났지만 일단 이정도로 마무리.
끝.
'공부 > 프로그래밍' 카테고리의 다른 글
[aws] cloudfront 와 도메인 연결(Alternate Domain Names (CNAMEs))때 주의점 (0) | 2021.04.30 |
---|---|
[ec2] amazon linux2 에다 mysql 8 버전 설치 (0) | 2021.04.28 |
[swagger3] 설정 및 authroize button 활성화하기(Bearer 사용) (0) | 2021.04.23 |
[jquery] file upload form을 ajax로 전송하기 (1) | 2021.04.21 |
[react] 하위 Component에서 children 을 지정하지 않아 에러가 나는 경우-TS2322: Type '{ children: never[];... (0) | 2021.04.12 |
댓글