본문 바로가기

💻Spring

Response 규격화 Swagger 처리

반응형

개요

사이드 프로젝트 중, 프론트쪽 친구가 응답을 통일성있게 규격화 시켜달라는 요청이 있어 응답을 다음과 같이 통일화 시켰다.

 

 

기존 코드

    @PostMapping("/jwt/refresh")
    @ResponseBody
    public ResponseEntity<RefreshAccessTokenResponseDto> refreshAccessToken(@RequestHeader(value = "Authorization") String refreshToken){
        RefreshAccessTokenResponseDto response = jwtService.validateRefreshToken(refreshToken);
        return ResponseEntity.ok(response);
    }

 

ApiCommonResponse 생성

@Getter
@Builder
@Schema(description = "응답")
@AllArgsConstructor
@NoArgsConstructor
public class ApiCommonResponse {
    @Schema(description = "Http 응답 코드")
    private Integer statusCode;

    @Schema(description = "응답 데이터")
    private Object data;
}

 

수정 1

@PostMapping("/member/logout")
@ResponseBody
public ResponseEntity<ApiCommonResponse> logout(@RequestHeader(value = "Authorization") String refreshToken){
    oAuthService.logout(refreshToken);
    ApiCommonResponse response = ApiCommonResponse.builder()
            .statusCode(200)
            .data("정상적으로 로그아웃이 되었습니다.")
            .build();
    return ResponseEntity.ok(response);
}

하지만 이렇게 data에 Object 타입을 두니 타입의 불안정성이 높아질 것 같아 제네릭 타입을 도입하여 타입의 안전성을 높여봤다.

 

ApiCommonResponse 수정

@Getter
@Builder
@Schema(description = "응답")
@AllArgsConstructor
@NoArgsConstructor
public class ApiCommonResponse<T> {
    @Schema(description = "Http 응답 코드")
    private Integer statusCode;

    @Schema(description = "응답 데이터")
    private T data;
}

 수정 2

@PostMapping("/jwt/refresh")
@ResponseBody
public ResponseEntity<ApiCommonResponse<RefreshAccessTokenResponseDto>> refreshAccessToken(@RequestHeader(value = "Authorization") String refreshToken){
    RefreshAccessTokenResponseDto responseDto = jwtService.validateRefreshToken(refreshToken);

    ApiCommonResponse response = ApiCommonResponse.builder()
            .statusCode(200)
            .data(responseDto)
            .build();
    return ResponseEntity.ok(response);
}

이렇게 응답 코드, 데이터로 묶어 모든 컨트롤러에 응답을 통일성있게 가져갔다.

 

하지만, Swagger가 익숙치 않아 어떻게 할 지 Chat GPT에게 물어봤더니

재사용 하여 작업할 순 없고 Dto 별로 Wrapper 클래스를 만들어서 응답을 주라는 것이다...!!

 

도저히 Swagger 때문에 응답별 DTO용 Wrapper 클래스를 만드는건 용납 할 수 없었기 때문에 

구글링을 하다 갓택 오버플로우의 도움을 받을 수 있었다!

https://stackoverflow.com/questions/33459644/how-to-specify-a-generic-type-class-for-swagger-api-response 

 

How to specify a generic type class for Swagger API response

I have about 40 APIs that have similar base response structure as follows: { "lastAccessed": "2015-30-08:14:21:45T", "createdOn": "2015-30-07:09:04:10T", "lastModified": "2015-30-08:14...

stackoverflow.com

 

@Operation(summary = "access token 재발급 메서드", description = "access token 재발급 메서드입니다.")
@ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "access 토큰 재발급", useReturnTypeSchema = true),
        @ApiResponse(responseCode = "401", description = "access 토큰 재발급 실패(올바르지 않은 refresh token)", content = @Content(schema = @Schema(implementation = ApiErrorResponse.class)))
})

 

이렇게 userReturnTypeSchema를 이용하면

메서드의 리턴 타입을 확인하여 제네릭 타입 별로 Swagger에 표현을 할 수 있게된다!

 

성공!

 

추가로 Chat GPT에게 학습까지 시켜주면서 이슈(?)를 마무리 해보았다!

반응형