스웨거를 사용하면 다음과 같이 어노테이션만 사용해도 자동으로 api명세를 해줍니다

로컬에서 스웨거에 접속해 명세를 확인한 모습

정상적인 케이스의 응답 형태뿐만 아니라 예외 관련 응답도 명세할 필요가 있었습니다.

스웨거에서는 `@ApiResponse`를 통해 다음과 같이 명세를 생성할 수 있었습니다.

하지만 위와 같은 방식은 2가지 문제가 존재합니다.

1. 실제 비즈니스 로직은 노란색 박스로 매우 적은데도 불구하고 명세와 관련한 코드가 훨씬 많은 비중을 차지합니다.

2. 로그인과 관련한 에러는 여러 api에서 공통으로 쓰일 것입니다. 만약 응답의 형태가 바뀐다면 전부 바꿔주어야 겠죠...?

 

이러한 문제를 해결하고자 커스텀 어노테이션을 만들어서, 여기에 예외 클래스를 인자로 전달하는 방식을 생각했습니다.

먼저, SwaggerExceptionResponse라는 스웨거의 예외 응답 전용 커스텀 어노테이션을 만들었습니다.

여기에는 예외 클래스의 배열을 인자로 전달받도록 했습니다.

 

스웨거는 OperationCustomizer 타입의 명세를 커스터마이징 할 수 있는 인터페이스를 제공하고 있습니다.

빈 설정 파일에서 위와 같이 OperationCustomizer를 커스텀해서 응답 정보들을 추가해 빈으로 등록하면 스웨거가 추가한 정보들에 맞게 명세 문서를 생성해 줍니다.

 

스웨거에서 명세를 하기 위한 객체의 그래프는 다음과 같이 설계되어 있습니다.

Operation -> ApiResponses -> ApiResponse

저희가 원하는 것은 예외 클래스에 있는 응답 정보들을 ApiResponse에 추가하는 것입니다.

 

setUpApiResponses 메서드에서는 각 예외 클래스마다 응답들로 ApiResponse를 생성해서 ApiResponses에 추가하도록 했습니다.

 

Exception에 들어있는 정보들을 추출하기 위해서는 Class타입으로 전달받은 예외 객체를 생성해주어야 합니다.

 

위 코드와 같이 extractExceptionFrom 메서드를 통해서 class로 전달받았던 예외 객체를 리플렉션을 통해 생성했습니다.

 

아래는 ApiResponse 객체에 응답 정보들을 추가하는 코드입니다.

Content를 생성해서 응답의 형태를 구성했습니다.

저희가 명세하고자 하는 응답의 형태는 message와 code입니다.

Exception에 담겨있는 정보를 꺼내서 다음과 같은 형태로 명세하고자 했습니다

message: ""

code: ""

ExceptionSituation은 응답의 형태이고

ExceptionMapper에서 Map<Class<? extends Exception>, ExceptionSituation>의 형태로 Class와 그에 해당하는 정보를 매핑하고 있습니다.

 

이제 커스터마이징이 완료됐습니다.

다음과 같이 어노테이션에 Exception class들을 인자로 전달만 하면 자동으로 예외 명세가 생성됩니다.

스웨거에서 생성된 결과를 확인해 보겠습니다.

자동으로 생성하면서도 훨씬 더 자세하고 깔끔한 모습입니다.

 

http 상태 코드뿐만 아니라 저희만의 에러 코드도 명세했습니다.

 

각 빨간색 박스는 코드에서 설정했던 name, description, ObjectSchema입니다.

 

이렇게 스웨거를 커스텀해서 자동으로 예외 응답을 생성하도록 만들어 봤습니다.

자동으로 생성하면서도 더 자세히 명세할 수 있었고, 예외 클래스를 통해 명세하므로 더 편하고 변경에도 영향을 받지 않도록 만들었습니다.

+ Recent posts