2 분 소요

협업 시 공유할 API 문서를 만들기 위해 Swagger를 적용했고 어떻게 설정했는지 기록했다!

Configuration

Swagger 설정에 필요한 기능을 사용하기 위해 build.gradle에서 다음 내용을 추가하고 generate 해주자.
여기서 적절한 버전을 사용하지 않으면 이후에 Unable to render this definition 에러가 발생할 것이다.

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


SwaggerConfig 클래스를 만들어 다음 내용을 적어주자. @Configuration을 빠뜨리지 않도록 주의!

@Configuration
public class SwaggerConfig {

    @Bean
    public OpenAPI openAPI(@Value("${springdoc.version}") String springdocVersion) {
        Info info = new Info()
                .title("Swagger API Docs")
                .version(springdocVersion)
                .description("API Docs 설명");

        return new OpenAPI()
                .components(new Components())
                .info(info);
    }
}
  • ${springdoc.version} : @Value를 사용해 Springdoc 버전 내용을 application.yml에서 가져옴

application.yml에도 swagger 설정에 필요한 내용을 적어줘야 한다.
여기까지 했다면 localhost:{port#}/swagger-ui/index.html에서 Swagger 페이지까지 접속할 수 있을 것이다!

springdoc:
  version: V1
  packages-to-scan: com.example.name
  swagger-ui:
    path: /api-docs
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /api-docs/json
    groups:
      enabled: true
  cache:
    disabled: true
  default-consumes-media-type: application/json;charset=UTF-8
  default-produces-media-type: application/json;charset=UTF-8
  • version : 위에서 파라미터로 받던 ${springdoc.version} 값을 설정해주는 부분으로, swagger 문서 버전을 의미
  • packages-to-scan : 스캔할 API 경로 지정
  • path : swagger-ui는 해당 문서 경로를, api-docs는 해당 문서의 json 형식 경로를 의미
    • /api-docs로 설정돼 있으므로 localhost:{port#}/api-docs로 접속 가능
  • tags-sorter : 태그 정렬 순서
  • operations-sorter : API 정렬 순서
  • groups.enabled : 그룹화 기능 활성화 여부

Controller

API가 정의돼 있는 즉, @RestController가 적용된 컨트롤러만 스캔해서 Swagger 문서에 표시하게 되는데 각 컨트롤러마다
태그를 설정해서 해당 컨트롤러의 제목이나 설명을 적을 수 있다.

@Tag(name = "유저", description = "유저 서비스 관련 API") //태그 적용
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class UserController {
    ...
}


그리고 API 메소드마다 내용도 수정해줄 수 있다! 아래는 마이페이지 조회 API이다.

@Operation(summary = "마이페이지 조회 메소드")
@ApiResponses(value = {
    @ApiResponse(responseCode = "200", description = "SUCCESS", content = @Content(schema = @Schema(implementation = UserDto.class))),
    @ApiResponse(responseCode = "400", description = "BAD REQUEST", content = @Content(schema = @Schema(implementation = UserDto.class)))
})
@GetMapping("/user/edit")
public ResponseEntity<?> edit(Long userId) {
    UserDto userDto = userService.info(userId);
    return new ResponseEntity<>(userDto, HttpStatus.OK);
}
  • @Operationsummary에 해당 API의 설명을 적어줄 수 있음
  • @ApiResponse에 각 응답 결과(responseCode)에 따라 내용(content)을 설정해줄 수 있음
    • 어떤 타입이 응답으로 나가는지 그대로 보여주고 싶다면 @Schema를 통해 클래스를 등록하면 됨

응답으로 나가는 객체가 1개가 아니라 여러개(List, Page 등)일 수 있다. 그럴땐 array@ArraySchema를 적용하자.

@ApiResponse(responseCode = "200",
            description = "SUCCESS",
            content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProductPreviewDto.class))))


만약 String을 내보내는데 예시까지 설정하고 싶다면 다음과 같이 설정해주자.

    @ApiResponse(responseCode = "200",
            description = "SUCCESS",
            content = @Content(mediaType = "application/json", 
                               schema = @Schema(type = "string"), 
                               examples = @ExampleObject(value = "\"API 호출 성공\"")))
  • mediaTypeexamples를 추가로 설정해주기
  • schematype 설정까지 해주기

Swagger UI 수정하기 (CSS)

접속 경로가 localhost:{port#}/swagger-ui이므로 해당 경로에 맞게 컨트롤러를 설정해주고,
기존 Swagger UI에 적용되던 css 파일과 내 css 파일을 합쳐준 뒤 반환해주면 된다.
이 때 내 css 파일은 /swagger-ui.css로 설정한다면 resources/swagger-ui.css에 위치해야 한다.
/swagger-ui.css가 아닌 swagger-ui.css로 등록하면 문제가 생길 수 있음에 주의!

@RestController
@RequestMapping("/swagger-ui")
public class SwaggerController {
    @GetMapping(path = "/swagger-ui.css", produces = "text/css")
    public String getCss() {
        String origin = toText(getClass().getResourceAsStream("/META-INF/resources/webjars/swagger-ui/4.18.2/swagger-ui.css"));
        String current = toText(getClass().getResourceAsStream("/swagger-ui.css"));
        return origin + current;
    }

    static String toText(InputStream in) {
        return new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
                .lines().collect(Collectors.joining("\n"));
    }
}
  • origin에 적인 swagger-ui.css 경로는 기존 Swagger UI에 적용되는 css 파일로 버전 4.18.2는 변경될 수 있으므로 확인 필요
  • @RestController가 아닌 @Controller를 적용하면 안됨

Swagger 문서에 표시되지 않도록 설정하기

SwaggerController를 어디에 정의했는지에 따라 달라지겠지만, Swagger 문서에는 스캔되지 않아야 한다.
@Hidden을 설정해주면 Swagger 스캔 대상에서 제외된다.

@Hidden
@RestController
@RequestMapping("/swagger-ui")
public class SwaggerController { ... }


References

카테고리:

업데이트:

댓글남기기