DS's TechBlog
[Spring] Swagger default 200 response 삭제하기 본문
[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);
}

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);
}

SuccessCode.UNIQUE_USER_ID, SuccessCode.DUPLICATED_USER_ID 는 200번 응답 코드를 가집니다.
200번 응답 코드를 설정했을 때는 기존의 Default 200 response가 사라진 것을 볼 수 있습니다.
해결 접근법
- 모든 요청의 성공에 대한 응답으로 200번을 반환한다면 해결할 수 있습니다.
- 하지만, 회원가입과 같이 POST로 들어오는 요청을 성공적으로 수행하여 서버가 새 리소스를 작성했을 때는 201번 코드를 내려줘야 합니다. 모든 요청에 대해서 200번 코드를 반환하게 된다면, HTTP 상태 코드가 가지는 표준화된 의미에 위배되어 클라이언트에서 오류를 처리하기 힘들어집니다. - Spring 설정 파일에 springdoc.override-with-generic-response=false 구문을 추가합니다.
- Swagger2의 Docket에 useDefaultResponseMessages(false) 옵션을 적용한 것과 같은 효과로 기본적으로 제공하는 응답을 사용하지 않겠다는 의미입니다. 하지만, 저는 해결되지 않았습니다. - 공식문서에 따라서 아래 구문을 컨트롤러에 추가 해주었습니다.
- 하지만, 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);
}
ApiResponses의 remove 메서드를 통해 200번 응답을 삭제한 후 직접 정의한 커스텀 어노테이션의 코드를 ApiResponses에 적용시켜 줌으로써 해결하였습니다. SwaggerConfig의 구성은 이전 포스팅에서 볼 수 있습니다.

커스텀 어노테이션의 응답을 추가하는 코드에서 기본적으로 제공하는 200번 코드에 대한 응답을 제거해서 문제를 해결했습니다. 간단하게 해결할 수 있는 문제였지만, 관련 내용이 부족해 해결하는 데 시간이 꽤 소요되었습니다.
'Java & Spring' 카테고리의 다른 글
[Spring] AWS S3 + Spring Boot 3.2 설정 및 적용하기 (1) | 2024.06.09 |
---|---|
[Spring Security] authorizeHttpRequests 우선순위 적용하기 (1) | 2024.05.17 |
[Spring] Swagger 공통 응답 코드 처리 및 Enum으로 정의한 응답 코드 사용하기 (0) | 2024.05.03 |
[Spring Security] SecurityFilterChain에서 발생하는 예외를 처리하기 (0) | 2024.04.24 |
[Spring Security] 로그인 입력 값을 Json 형태 + userId로 받기 (1) | 2024.04.19 |