ํ๋ก์ ํธ ๊ธฐ๋ณธ ์ธํ
2. [๋ฐฑ์๋] Swagger, Response Model, ์์ธ ์ฒ๋ฆฌ ์ธํ
Swagger Setting
๋ฐฑ์๋ ์ด๊ธฐ ์ธํ
๋ build.gradle์ ์ค์ ํ๋ Swagger๋ฅผ ์ธํ
ํ๋ค.
Swagger์ ๋ํ ๊ธฐ๋ณธ ์ธํ
์ ํด์ฃผ๋ SwaggerConfig.java
๋ฅผ ๋ง๋ค๊ณ , Security์์๋ web.ignoring() ์ค์ ์ ํด์ฃผ์๋ค.
SwaggerConfig.java
package com.portfolio.backend.config.swagger;
// import ์๋ต
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(swaggerInfo()).select()
.apis(RequestHandlerSelectors.basePackage("com.portfolio.backend"))
.paths(PathSelectors.any())
.build()
.useDefaultResponseMessages(false);
}
private ApiInfo swaggerInfo() {
return new ApiInfoBuilder().title("Portfolio For Developers API Documentation")
.description("๊ฐ๋ฐ์๋ฅผ ์ํ ํฌํธํด๋ฆฌ์ค ํ๋ก์ ํธ API ์ฐ๋ ๋ฌธ์")
.license("vividswan").licenseUrl("https://vividswan.github.io/").version("1").build();
}
}
SecurityConfig.java
package com.portfolio.backend.config.security;
// import ์๋ต
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override // ignore check swagger resource
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/v2/api-docs", "/swagger-resources/**",
"/swagger-ui.html", "/webjars/**", "/swagger/**");
}
}
Api Response Model Setting
Response ํ์์ ํต์ผํ๊ธฐ ์ํด Response Model ๊ฐ์ฒด๋ฅผ ๋ง๋ค์๋ค.
Response์ ์ฑ๊ณต ์ฌ๋ถ, ์ฝ๋๋ฒํธ, ๋ฉ์์ง๋ฅผ ๋ด๋ CommonResponse
์ ์ด๋ฅผ ์์ํ์ฌ ๋จ์ผ Data๋ฅผ Return ํ๋ SingleResponse<T>
์ ๋ฆฌ์คํธ Data๋ฅผ Return ํ๋ ListResponse<T>
๊ฐ์ฒด๋ฅผ ๋ง๋ค์๋ค.
์ด๋ฅผ ์ํฉ์ ๋ง๊ฒ Return ํด์ค ์ ์๋ ResponseService
๋ผ๋ Service ๊ฐ์ฒด๋ฅผ ๋ง๋ค์๋ค.
CommonResponse.java
package com.portfolio.backend.model.response;
// import ์๋ต
@Getter
@Setter
public class CommonResponse {
@ApiModelProperty(value = "Response ์ฑ๊ณต ์ฌ๋ถ")
private boolean isSuccess;
@ApiModelProperty(value = "Response ์ฝ๋ ๋ฒํธ")
private int code;
@ApiModelProperty(value = "Response Message")
private String message;
public CommonResponse(){}
public CommonResponse(String msg){
this.message = msg;
};
}
SingleResponse.java
package com.portfolio.backend.model.response;
// import ์๋ต
@Setter
@Getter
public class SingleResponse<T> extends CommonResponse{
@ApiModelProperty(value = "Single Response Data")
private T data;
}
ListResponse.java
package com.portfolio.backend.model.response;
// import ์๋ต
import java.util.List;
@Getter
@Setter
public class ListResponse<T> extends CommonResponse{
@ApiModelProperty(value = "Response Data List")
private List<T> list;
}
ResponseService.java
package com.portfolio.backend.model.response;
// import ์๋ต
@Service
public class ResponseService {
public <T> SingleResponse<T> getSingleResponse(T data){
SingleResponse<T> res = new SingleResponse<>();
res.setData(data);
res.setCode(0);
res.setMessage("Success");
res.setSuccess(true);
return res;
}
public <T> ListResponse<T> getListResponse(List<T> list){
ListResponse<T> res = new ListResponse<>();
res.setList(list);
res.setCode(0);
res.setMessage("Success");
res.setSuccess(true);
return res;
}
public CommonResponse getSuccessResponse(){
CommonResponse res = new CommonResponse();
res.setSuccess(true);
res.setCode(0);
res.setMessage("Success");
return res;
}
public CommonResponse getFailResponse(String msg){
CommonResponse res = new CommonResponse(msg);
res.setSuccess(false);
res.setCode(-1);
res.setMessage(msg);
return res;
}
}
Exception Handler Setting
์ฐ์ ๋ ๊ฐ์ง ์์ธ ํด๋์ค๋ฅผ ๋ง๋ค์๋ค.
๊ทธ ํ ์ ์ญ์ผ๋ก ์์ธ ์ฒ๋ฆฌ๋ฅผ ์ปจํธ๋กค(@RestControllerAdvice
์ด๋
ธํ
์ด์
) ํ ์ ์๋ ExceptionAdvice์ ์ ์ธํ์ฌ ์์ธ ์ฒ๋ฆฌ ๊ณ ๋ํ๋ฅผ ํด์ค๋ค.
CustomValidationException
package com.portfolio.backend.config.advice.exception;
public class CustomValidationException extends RuntimeException{
public CustomValidationException() {
super();
}
public CustomValidationException(String message) {
super(message);
}
public CustomValidationException(String message, Throwable cause) {
super(message, cause);
}
}
CustomUserNotFoundException
package com.portfolio.backend.config.advice.exception;
public class CustomUserNotFoundException extends RuntimeException{
public CustomUserNotFoundException() {
super();
}
public CustomUserNotFoundException(String message) {
super(message);
}
public CustomUserNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
ExceptionAdvice
package com.portfolio.backend.config.advice;
// import ์๋ต
@RequiredArgsConstructor
@RestControllerAdvice
public class ExceptionAdvice {
private final ResponseService responseService;
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
protected CommonResponse defaultException(HttpServletRequest request, Exception e) {
return responseService.getFailResponse("Default Error");
}
@ExceptionHandler(CustomUserNotFoundException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
protected CommonResponse userNotfoundException(HttpServletRequest req, CustomUserNotFoundException e){
return responseService.getFailResponse("์ ๋ชป ๋ User ์ ๋ณด ์
๋๋ค.");
}
@ExceptionHandler(CustomValidationException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
protected CommonResponse validationException(HttpServletRequest req, CustomValidationException e){
return responseService.getFailResponse("์ ๋ชป ๋ ์
๋ ฅ ๊ฐ์
๋๋ค.");
}
}