개발이군고구마

[전전긍긍 설정세팅] 2. Swagger API 명세 (#공통규약) 본문

SERVER/Architecture

[전전긍긍 설정세팅] 2. Swagger API 명세 (#공통규약)

김구황 2025. 5. 19. 23:47
728x90

api 명세 마저도...

 

💌 코딩 천재분들께 붙히는 레터

 

설마 이것까지 연습해야하는거야? 라고 깜짝놀라신다면 ^_^ 

그래요 사실 swagger 마저도 능수능난하게 쓰진 못해요 제가.... (대체 뭘 잘하는 거..?) 

그러면 어떱니까. 이참에 한번 써보고 앞으로 척척 할 수 있으면 되죠... 능력이 없어서 알 일만 남았다구요 😉

 


1. 라이브러리 설치 

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'

 

☑️  http://localhost:8080/swagger-ui/index.html 접속 

 

2. (보안) swagger 시큐리티 설정 추가 

swagger는 dev 배포 환경에서만 사용해도 되기 때문에,

운영/개발 서버가 분리되어 배포되는 경우 swagger 설정은 dev.yml 에만 해주는 것이 좋다 

springdoc:
  api-docs:
    path: /api-docs
  swagger-ui:
    path: /swagger-ui.html
    enabled: true # 실제 운영환경에서는 false로! 이 부분은 덮어 씌워서 읽음
    tags-sorter: alpha
    operations-sorter: alpha

☑️ 현재 사이드 프로젝트에선 운영과 개발 서버가 같기 때문에 이 부분은 크게 신경써주지 않는다. 

 

 

💥  그렇게 되면 모든 ip에 공개된 도메인에서 swagger에 무작위로 접속할 수 있기 때문에, spring security에서 /swagger-ui.html 등으로 오는 요청에 대해서 로그인을 하도록 강제할 필요가 있다. 

spring:
  security:
    user:
      name: swaggeruser
      password: swaggerpw

 

 

3. config 파일 생성 

@Configuration
public class Swagger {
    @Bean
    public OpenAPI openAPI(){
        return new OpenAPI()
                .info(new io.swagger.v3.oas.models.info.Info()
                        .title("Pratice API")
                        .version("v1.0.0")
                        .description("Pratice API 명세서"));
    }
}

 

 

 

4. 이용 테스트 

  • User 라는 가장 큰 범주(Controller)를 사용할 예정
  • 사용할 메인 api 명은 "api/users"
  • 응답은 공통으로 정의한 CommonResponse 또는 ExceptionResponse를 사용

1) POST

  • 메서드는 회원 등록 성격
  • 또한 정상 응답과 ExceptionHandler 에서 정의한 응답 코드 들에 대한 설명
  • 요청으로 넘어오는 객체는 TestEntity 
@Operation(summary = "게시글 생성", description = "게시글을 생성합니다.")
@ApiErrorStandard
@ApiResponse(
    responseCode = "200",
    description = "게시글 생성 성공",
    useReturnTypeSchema = true
)
@PostMapping
public ApiTemplate<PostResponse> createPost(@Valid @RequestBody PostRequest request) {
    PostResponse response = new PostResponse(
        1L,
        request.getTitle(),
        request.getContent(),
        "홍길동",
        LocalDateTime.now()
    );
    return ApiTemplate.ok(ExamplePostResponseMessage.POST_CREATED, response);
}

 

API 카테고리화 해줌 

@Tag(name = "User", description = "사용자 관련 API")

 

API 에 대한 설명 제공 

@Operation(summary = "회원 등록", description = "새로운 사용자를 등록합니다.")

 

 

 

요청값 - TestEntity / 응답값 - CommonResponse

Schema 로 정의하면 우측 그림과 같이 설명과 함께 볼 수 있음 

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Schema(description = "TEST DTO")
public class TestEntity {
    @Schema(description = "이름", example = "홍길동")
    private String name;
    @Schema(description = "나이", example = "20")
    private int age;

    public TestEntity updateName(String name) {
        this.name = name;
        return this;
    }
}

 

 



정의한 응답 코드 

@ApiResponse(
    responseCode = "200",
    description = "게시글 생성 성공",
    useReturnTypeSchema = true
)

성공의 경우에만 정의해주고, 에러의 경우엔 @annotation으로 따로 빼서 만듦 

아래의 코드 블록은 어떤 코드의 값들이 나오는지 보여주는 역할 

ApiResponse로 정리한 값들은 우선 아래에 예시 문장으로 뜨게 되어있음 / 성공 응답의 예시

 

 

 

 

 

👋🏻 여기서 잠깐 문법 학습

   @ApiResponse에 responseCode, description를 정의했는데 왜 서버에러가 나오면 기본 응답이 나오나?

  •  Swagger UI에서 "이런 식으로 응답이 올 거야"를 문서화 하는 역할
  • ExceptionHandler에서 에러를 잡아서 다시 코드로 만들어줄 수 있음 



 

☑️ ExceptionHandler를 적용했을 때의 화면 

- 메세지 interface -> Enum : enum 에 구현할 생성자 필드들에 대한 get형태로 인터페이스를 작성 -> enum은 @Getter 

- 예외 CustomExcpetion : 그 메세지를 받는 예외

- ExceptionHandler : 예외를 캐치하는 핸들러 (가장 상단에는 최상단 에러객체에 대한 메세지 전달 주로 Exception)

- 응답 Response : 최종적으로 받은 메세지를 틀에 맞게 보내주는 객체 

 

 

 

 

 

2) PUT 

위에 코드와 많이 비슷하지만 pathVarialble 로 id 값을 api에 입력한다는 걸 알려줄 수 있음

@PutMapping("/{id}")
@Operation(summary = "회원 수정", description = "기존 사용자의 정보를 수정합니다.")
@ApiResponse(responseCode = "200", description = "회원 수정 성공")
@ApiResponse(
        responseCode = "500",
        description = "서버 내부 오류",
        content = @Content(
                mediaType = "application/json",
                schema = @Schema(implementation = ExceptionResponse.class),
                examples = @ExampleObject(
                        name = "ServerError",
                        summary = "알 수 없는 서버 오류 예시",
                        value = """
                {
                  "success": false,
                  "message": "알 수 없는 서버 에러가 발생했습니다."
                }
            """
                )
        )
)
public CommonResponse<?> updateUser(		@Parameter(
        name = "postId",
        description = "수정할 게시글의 ID",
        in = ParameterIn.PATH,
        required = true,
        example = "1"
    )@PathVariable Long id, @RequestBody TestEntity testEntity) {
    // 회원 수정 로직
    try {
        TestEntity updatedUser = testEntity.updateName("Updated Name");
        return CommonResponse.ok(() -> "성공", updatedUser);
    } catch (Exception e) {
        throw new RuntimeException("서버 오류 발생");
    }
}

 

 

 @ExampleObject : 참고용 문서에 넣는 내용 

 @Schema : 아래 스키마에 정리됨 

content = @Content(
                mediaType = "application/json",
                schema = @Schema(implementation = ExceptionResponse.class),
                examples = @ExampleObject(
                        name = "ServerError",
                        summary = "알 수 없는 서버 오류 예시",
                        value = """
                {
                  "success": false,
                  "message": "알 수 없는 서버 에러가 발생했습니다."
                }
            """
                )
        )

 

 

 


참고문헌

https://velog.io/@zo_meong/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-7-Swagger-%EC%A0%81%EC%9A%A9-springdoc

 

[Project] Swagger 적용 (springdoc)

Swagger는 REST API를 문서화하고 사용자가 쉽게 테스트할 수 있도록 도와주는 도구이다. 개발자가 문서를 직접 작성하지 않아도 되며 API 버전 관리가 용이해진다는 장점을 가지고 있다.Spring Boot 프

velog.io