목적 추천 방식
| API 이름/설명 | @Operation(summary, description) |
| 응답 DTO 설명 | DTO 클래스/필드에 @Schema |
| 공통 오류 응답 | Controller @ApiResponses 또는 Global |
| API 그룹 | @Tag(name="User API") |
| ResponseEntity schema 명시 | 필요 없음 |
예시)
@RestController
@RequestMapping("/api/v1/user")
@Tag(name = "User API", description = "사용자 관련 기능")
@ApiResponses({
@ApiResponse(responseCode = "400", description = "잘못된 요청"),
@ApiResponse(responseCode = "500", description = "서버 오류")
})
public class UserController {
@Operation(summary = "회원 조회", description = "ID로 회원 정보를 조회한다.")
@GetMapping("/{id}")
public ResponseResponse<UserDto> getUser(@PathVariable Long id) {
...
}
}
SwaggerConfig 설정
- 설정에서 공통 오류 응답에 대해서 작성
- User, Admin 으로 그룹화
- 컨트롤러에서 ResponseEntity의 경우 @Scheme 를 넣지 않아도 만들어줌
package com.pudding.base.config;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@OpenAPIDefinition(
info = @Info(
title = "API 문서",
description = "",
version = "v1"
)
)
@Configuration
public class SwaggerConfig {
private static final String BEARER_TOKEN_PREFIX = "Bearer";
/**
* 공통 Security 설정 (JWT)
*/
@Bean
public OpenAPI openAPI() {
String jwtName = "JWT";
SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtName);
Components components = new Components()
.addSecuritySchemes(
jwtName,
new SecurityScheme()
.name(jwtName)
.type(SecurityScheme.Type.HTTP)
.scheme(BEARER_TOKEN_PREFIX)
.bearerFormat(jwtName)
);
return new OpenAPI()
.addSecurityItem(securityRequirement)
.components(components);
}
/**
* 공통 오류 응답
*/
@Bean
public OpenApiCustomizer globalResponsesCustomizer() {
return openApi -> {
openApi.getPaths().values().forEach(pathItem ->
pathItem.readOperations().forEach(operation -> {
operation.getResponses().addApiResponse("400",
new ApiResponse().description("잘못된 요청(Validation 실패)"));
operation.getResponses().addApiResponse("401",
new ApiResponse().description("인증 실패(JWT 누락/만료)"));
operation.getResponses().addApiResponse("403",
new ApiResponse().description("권한 부족"));
operation.getResponses().addApiResponse("404",
new ApiResponse().description("리소스를 찾을 수 없음"));
operation.getResponses().addApiResponse("409",
new ApiResponse().description("중복/충돌 발생"));
operation.getResponses().addApiResponse("429",
new ApiResponse().description("요청 과다(Throttle 제한)"));
operation.getResponses().addApiResponse("500",
new ApiResponse().description("서버 내부 오류"));
operation.getResponses().addApiResponse("503",
new ApiResponse().description("서비스 이용 불가(점검/장애)"));
})
);
};
}
/**
* 사용자용 API 문서 그룹
*/
@Bean
public GroupedOpenApi userApi(OpenApiCustomizer globalResponsesCustomizer) {
return GroupedOpenApi.builder()
.group("UserAPI")
.pathsToMatch("/api/v1/**")
.pathsToExclude("/api/v1/admin/**") // 관리자 제외
.addOpenApiCustomizer(globalResponsesCustomizer)
.build();
}
/**
* 관리자용 API 문서 그룹
*/
@Bean
public GroupedOpenApi adminApi(OpenApiCustomizer globalResponsesCustomizer) {
return GroupedOpenApi.builder()
.group("AdminAPI")
.pathsToMatch("/api/v1/admin/**")
.addOpenApiCustomizer(globalResponsesCustomizer)
.build();
}
/**
* 사용자용 API 문서 그룹
*/
@Bean
public GroupedOpenApi clientAPI(OpenApiCustomizer globalResponsesCustomizer) {
return GroupedOpenApi.builder()
.group("ClientAPI")
.pathsToMatch("/api/v1/client/**")
.addOpenApiCustomizer(globalResponsesCustomizer)
.build();
}
}
'Tech Archive > SpringBoot' 카테고리의 다른 글
| [SpringBoot] PM2 JAR파일 배포 및 JDK, Apache 서버 세팅 (0) | 2026.06.18 |
|---|---|
| [SpringBoot] 백엔드 개발환경 세팅하기 (0) | 2026.05.21 |