Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

DS's TechBlog

[Spring] Swagger default 200 response 삭제하기 본문

Java & Spring

[Spring] Swagger default 200 response 삭제하기

dsjo 2024. 5. 3. 21:49
 

[Spring] Swagger 공통 응답 코드 처리 및 Enum으로 정의한 응답 코드 사용하기

Swagger로 API 문서를 작성하는 데 몇 가지 문제가 있었습니다.1. 공통 응답 코드는 Swagger-ui에 표시되지 않습니다.2. Enum으로 정의한 응답 코드와 메시지를 @ApiResponse에서 사용할 수 없습니다.문제 코

dsjo.tistory.com

Swagger 공통 응답 코드를 처리하기 위해, 위 글에서 커스텀 어노테이션을 적용하였습니다.

하지만, 설정하지 않은 200번 응답이 default로 보이게 되는 문제가 생겼습니다.

문제가 생긴 원인과 해결 방법에 대해서 알아보겠습니다.

문제점

    @ApiSuccessCodeExample(SuccessCode.JOIN_SUCCESS)
    @ApiErrorCodeExamples({ErrorCode.DUPLICATED_USER_ID, ErrorCode.DUPLICATED_STUDENT_NUMBER, ErrorCode.INVALID_PARAMETER})
    @PostMapping
    public ResponseEntity<SuccessResponse> resisterUser(@RequestBody @Valid JoinDTO joinDTO) {
        joinService.createUserAccount(joinDTO);

        return ResponseUtil.buildSuccessResponseEntity(SuccessCode.JOIN_SUCCESS);
    }

 

200번 응답을 설정하지 않았을 때 swagger-ui

SuccessCode_JOIN_SUCCESS 는 201번 응답 코드를 가집니다. 성공 코드로 201번 응답만 반환하도록 하였지만, 위와 같이 200번에 해당하는 응답도 자동으로 생성된 것을 볼 수 있습니다.

    @Operation(summary = "ID 중복확인")
    @Parameter(name = "userId", description = "중복 확인할 ID")
    @ApiSuccessCodeExamples({SuccessCode.UNIQUE_USER_ID, SuccessCode.DUPLICATED_USER_ID})
    @GetMapping("/check-user-id")
    public ResponseEntity<SuccessResponse> checkUserIdDuplicate(@RequestParam String userId) {
        SuccessCode successCode = SuccessCode.UNIQUE_USER_ID;
        if (joinService.isUserIdDuplicate(userId)) {
            successCode = SuccessCode.DUPLICATED_USER_ID;
        }

        return ResponseUtil.buildSuccessResponseEntity(successCode);
    }

200번 응답을 설정했을 때 swagger-ui

SuccessCode.UNIQUE_USER_ID, SuccessCode.DUPLICATED_USER_ID 는 200번 응답 코드를 가집니다.

200번 응답 코드를 설정했을 때는 기존의 Default 200 response가 사라진 것을 볼 수 있습니다.

해결 접근법

  1. 모든 요청의 성공에 대한 응답으로 200번을 반환한다면 해결할 수 있습니다.
    - 하지만, 회원가입과 같이 POST로 들어오는 요청을 성공적으로 수행하여 서버가 새 리소스를 작성했을 때는 201번 코드를 내려줘야 합니다. 모든 요청에 대해서 200번 코드를 반환하게 된다면, HTTP 상태 코드가 가지는 표준화된 의미에 위배되어 클라이언트에서 오류를 처리하기 힘들어집니다.
  2. Spring 설정 파일에 springdoc.override-with-generic-response=false 구문을 추가합니다. 
    - Swagger2의 Docket에 useDefaultResponseMessages(false) 옵션을 적용한 것과 같은 효과로 기본적으로 제공하는 응답을 사용하지 않겠다는 의미입니다. 하지만, 저는 해결되지 않았습니다.
  3. 공식문서에 따라서 아래 구문을 컨트롤러에 추가 해주었습니다.
    - 하지만, 200번의 코드 내용만 사라지고, 코드 번호는 아래와 같이 그대로 보입니다.
@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) })

 

OpenAPI 3 Library for spring-boot

Library for OpenAPI 3 with spring boot projects. Is based on swagger-ui, to display the OpenAPI description.Generates automatically the OpenAPI file.

springdoc.org

문제 원인

기존에 @ApiResponse 를 사용해서 응답을 나타내줬을 때는 200번 코드가 생기지 않았습니다. 커스텀 어노테이션으로 응답을 나타내려고 하니 문제가 발생하였습니다. 아래 블로그에서 Swagger를 프로젝트에 적용하면, @ApiResponse 가 붙어있지 않은 컨트롤러 메서드에 대해서는 자동으로 200번 응답을 Swagger-ui에 보여준다는 것을 알았습니다.

 

[Spring Boot Tutorial] 15. Open API 3.0 + Swagger v3 상세설정

api 그룹 설정 : @Tag api Schema 설정 : @Schema api 상세 정보 설정 : @Operation api response 설정 : @ApiResponse api parameter 설정 : @Parameter 이전시간에 OpenAPI info 정보만 설정했었습니다. Schemas 에 대한 설명과 들

blog.jiniworld.me

해결법

@ApiResponse 가 붙어있지 않으면, 200번 응답이 자동으로 생성되는 것을 알았습니다. 하지만, @ApiResponse 를 커스텀 어노테이션으로 완전히 대체하고 싶었습니다. 그래서, SwaggerConfig에서 커스텀 어노테이션이 붙은 메서드에 대해서는 Default로 제공하는 200번 응답을 삭제해야 했습니다. 

    private void addExamplesToResponses(ApiResponses responses,
                                        Map<Integer, List<ExampleHolder>> statusWithExampleHolders) {
        
        // removedefault 200 code 
        if (responses != null && responses.containsKey("200")) {
            responses.remove("200");
        }

        statusWithExampleHolders.forEach(
                (status, v) -> {
                    Content content = new Content();
                    MediaType mediaType = new MediaType();
                    ApiResponse apiResponse = new ApiResponse();

                    v.forEach(
                            exampleHolder -> mediaType.addExamples(
                                    exampleHolder.getName(),
                                    exampleHolder.getHolder()
                            )
                    );
                    content.addMediaType("application/json", mediaType);
                    apiResponse.setContent(content);
                    responses.addApiResponse(String.valueOf(status), apiResponse);
                }
        );
    }

    private void addExamplesToResponses(ApiResponses responses, ExampleHolder exampleHolder) {
        Content content = new Content();
        MediaType mediaType = new MediaType();
        ApiResponse apiResponse = new ApiResponse();

        mediaType.addExamples(exampleHolder.getName(), exampleHolder.getHolder());
        content.addMediaType("application/json", mediaType);
        apiResponse.content(content);
        
        // removedefault 200 code 
        if (responses != null && responses.containsKey("200")) {
            responses.remove("200");
        }

        responses.addApiResponse(String.valueOf(exampleHolder.getHttpStatus()), apiResponse);
    }

ApiResponsesremove 메서드를 통해 200번 응답을 삭제한 후 직접 정의한 커스텀 어노테이션의 코드를 ApiResponses에 적용시켜 줌으로써 해결하였습니다. SwaggerConfig의 구성은 이전 포스팅에서 볼 수 있습니다.

default 200 code response가 사라진 swagger-ui

커스텀 어노테이션의 응답을 추가하는 코드에서 기본적으로 제공하는 200번 코드에 대한 응답을 제거해서 문제를 해결했습니다. 간단하게 해결할 수 있는 문제였지만, 관련 내용이 부족해 해결하는 데 시간이 꽤 소요되었습니다.