API Swagger 패턴, SwaggerConfig 설정하기

2026. 5. 21. 13:17·Tech Archive/SpringBoot

 

목적 추천 방식

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
'Tech Archive/SpringBoot' 카테고리의 다른 글
  • [SpringBoot] PM2 JAR파일 배포 및 JDK, Apache 서버 세팅
  • [SpringBoot] 백엔드 개발환경 세팅하기
roundfigure
roundfigure
알 수 없는 에러, 기술, 그리고 딱 떨어지는 해답. 사방으로 흩어진 모호한 문제들, 매끄러운 'Round Figure'로 정리하고 싶은 블로그.
  • roundfigure
    Round Figure
    roundfigure
  • 전체
    오늘
    어제
    • 전체 글 (56) N
      • Tech Archive (40)
        • Linux (2)
        • Linux(CentOS) (9)
        • Apache (4)
        • SpringBoot (3)
        • React (0)
        • Javascript (8)
        • JSTL (5)
        • 웹접근성 (4)
        • MySQL (2)
        • Unity (0)
        • ETC (3)
      • Trend (6) N
      • AI활용 (8) N
      • Hosting & Infra (2) N
      • Automation & Lab (0)
      • Error & Trouble Shooting (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • zeuz
    • hydok
  • 공지사항

  • 인기 글

  • 태그

    설치
    Anthropic Fable 5
    Opus 4.8 비교
    Claude 수출통제
    jquery
    웹접근성
    apache
    mysql
    javascript
    프로그래밍
    CentOS 7
    Proxy
    SWE-bench
    Linux
    Claude Fable 5
    Claude 접근 제한
    리눅스
    VPS 비교
    JSTL
    Claude Mythos 5
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
roundfigure
API Swagger 패턴, SwaggerConfig 설정하기
상단으로

티스토리툴바