Статьи
Утилиты Telegram YouTube Отзывы

Springdoc для документации REST API

Видеогайд Исходники

27 июля 2022

Тэги: gradle, Kotlin, rest, Spring Boot, руководство.

Содержание

  1. Подключаем springdoc
  2. Описание модели данных
  3. Описание rest-контроллера
  4. Как исключить параметр метода из springdoc
  5. Как исключить метод из springdoc
  6. Как исключить rest-контроллер из springdoc
  7. Настройки springdoc
  8. Миграция со springfox
  9. Выводы

Ранее я уже публиковал статью Подключение Swagger к Spring Boot для создания документации по REST API. К сожалению, с последними версиями Spring Boot описанный там подход уже не работает, т.к. на смену springfox-swagger пришёл springdoc. По функционалу springdoc предоставляет всё то же самое, но аннотации для разметки классов и методов нужно использовать другие. Поэтому в данной статье подробно рассмотрим пример документирования REST API с помощью springdoc и его отличия от springfox.

Springdoc – это библиотека для проекта на Spring Boot, которая автоматически будет генерировать документацию по вашему REST API на основании исходного кода и специальных аннотаций. Таким образом, ваша документация будет всегда актуальной и её не нужно как-то дополнительно актуализировать каждый раз при изменении исходников.

Подключаем springdoc

Для работы со springdoc в зависимости проекта достаточно добавить зависимость springdoc-openapi-ui. Также для реализации функционала самого REST API нам потребуется spring-boot-starter-web. В дальнейшем нам потребуется размечать наши сущности различными правилами валидации, поэтому добавим spring-boot-starter-validation.

Если вы пишете проект на Kotlin, то для правильной поддержки типов добавьте также springdoc-openapi-kotlin.

В итоге наш список зависимостей в gradle-проекте будет содержать следующее:

implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springdoc:springdoc-openapi-ui:1.6.9")
implementation("org.springdoc:springdoc-openapi-kotlin:1.6.9")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-actuator")
// другие стандартные зависимости...

Описание модели данных

Предположим, что наше приложение возвращает информацию о пользователях. Для начала создадим data-класс с уникальным номером пользователя и его фамилией, а также разметим этот класс правилами валидации:

@Schema(description = "Информация о пользователе")
data class PersonDto(
    @Schema(description = "Идентификатор")
    @Min(1)
    @Max(9999999999)
    val id: Int,

    @Schema(description = "Фамилия")
    @NotBlank
    @Size(min = 1, max = 100)
    val surname: String
)

Аннотация @Schema относится к самому springdoc и с помощью параметра description позволяет указывать описание как всей сущности в целом, так и каждого его поля.

Аннотации валидации @Min и @Max позволяют задавать минимальное и максимальное значения, которые допустимы для данного числового поля. Числовые идентификаторы в БД, как правило, не могут быть отрицательными, поэтому указываем, что они начинаются с 1.

Аннотация @NotBlank говорит о том, что фамилия не может быть пустой строкой, а аннотация @Size задаёт минимальную и максимальную длину фамилии.

Всю информацию об этих ограничениях, а также текстовые описания мы позднее увидим в веб-интерфейсе springdoc.

Описание rest-контроллера

Создадим простенький rest-контроллер PersonController, в котором будет всего 1 метод, возвращающий информацию о пользователе по его уникальному номеру.

@RestController
@RequestMapping("/persons")
@Tag(
    name = "Пользователи",
    description = "Все методы для работы с пользователями системы",
)
class PersonController {
    @GetMapping("/{id}")
    @Operation(summary = "Получить информацию о пользователе по его id")
    fun getPersonById(
        @Parameter(description = "id пользователя")
        @PathVariable("id") personId: Int
    ) = PersonDto(
        id = 42,
        surname = "Иванов"
    )
}

Здесь аннотация @Tag позволяет указать имя контроллера (в springdoc будет выделено жирным шрифтом) и его описание. @Operation позволяет сделать то же самое для методов этого контроллера, но описание надо указывать в параметре summary. Также можно указать назначение каждого параметра в методе с помощью @Parameter.

Теперь давайте запустим наше приложение локально и перейдём по адресу http://127.0.0.1:8080/swagger-ui/index.html. Это стандартный адрес, по которому доступен веб-интерфейс springdoc, но этот адрес можно переопределить с помощью параметра springdoc.swagger-ui.path в application.yml.

Открыв springdoc вы сможете увидеть всю ту информацию, которую мы уже определили: описание контроллера, метода, его параметров, а также возвращаемой модели. Кроме того, для модели мы видим также диапазоны возможных значений, которые могут в ней приходить. Из веб-интерфейса можно даже отправлять тестовые запросы напрямую.

Как исключить параметр метода из springdoc

Бывает необходимо исключить из документации некоторые служебные параметры. Например, информация о текущем пользователе может подставляться из данных авторизации автоматически, поэтому такой параметр не нужно передавать снаружи. В нашем примере давайте добавим в метод ещё один опциональный параметр под названием flag.

fun getPersonById(
    @Parameter(description = "id пользователя")
    @PathVariable("id") personId: Int,

    @Parameter(hidden = true)
    @RequestParam(required = false) flag: Boolean
)

Его необязательность определяет параметр required аннотации @RequestParam. А чтобы исключить его отображение в springdoc, достаточно указать аннотацию @Parameter с флагом hidden.

Как исключить метод из springdoc

Предположим, наше API предоставляет также информацию об администраторе системы. Но мы не хотим, чтобы из документации пользователи могли узнать о наличии такого метода.

@GetMapping("/admins")
@Operation(hidden = true)
fun getAdmin() = PersonDto(
    id = 1,
    surname = "Петров",
)

Аннотация @Operation с флагом hidden полностью исключает информацию о данном методе из документации.

Как исключить rest-контроллер из springdoc

Давайте теперь рассмотрим задачу сокрытия целого контроллера из sprindoc. Пусть у нас есть контроллер, который возвращает информацию о количестве средств на счёте любого пользователя по его id. Это приватная информация и в документации она фигурировать не должна.

@Hidden
@RestController
@RequestMapping("/balances")
class HiddenController {

    @GetMapping("/{personId}")
    fun getBalanceByPersonId(
        @PathVariable personId: Int,
    ) = BigDecimal("1000000")
}

Аннотация @Hidden скрывает весь rest-контроллер.

Тут важно заметить, что в реальных системах недостаточно просто скрыть какой-то параметр, метод или контроллер. Важно ещё и проверять права доступа каждого пользователя, который выполняет тот или иной запрос. Но мы тут этого не рассматриваем, т.к. это выходит за рамки данной статьи.

Настройки springdoc

По умолчанию вам настраивать ничего не нужно. Достаточно просто добавить зависимость и springdoc уже начнёт работать. Но если вам потребуется более тонко настроить springdoc, то в application.yml вы можете добавить любой необходимый параметр.

springdoc:
  show-actuator: false
  swagger-ui:
    enabled: true
    path: /swagger-ui.html

Параметр springdoc.show-actuator позволяет включать/выключать отображение служебных эндпоинтов spring-boot-starter-actuator, если у вас подключена такая зависимость.

Параметр springdoc.swagger-ui.enabled позволяет включать/выключать веб-интерфейс springdoc, а springdoc.swagger-ui.path – переопределять стандартный урл этого веб-интерфейса.

На самом деле параметров значительно больше. Все они описаны в официальной документации.

Миграция со springfox

Если в вашем проекте уже есть старая версия springfox-swagger, то вам достаточно удалить из зависимостей проекта всё, что связано со springfox, добавить то, что связано со springdoc и заменить аннотации в вашем коде по следующей таблице соответствий:

старый вариантновый вариант
@Api@Tag
@ApiIgnore@Parameter(hidden = true) или @Operation(hidden = true) или @Hidden
@ApiModel@Schema
@ApiModelProperty@Schema
@ApiParam@Parameter

Выводы

Как мы убедились, никаких принципиальных отличий между springfox и springdoc нет. Даже визуальных изменений в веб-интерфейсе swagger практически нет. Изменились только аннотации. При этом для новых версий Spring Boot стандартом является именно springdoc, поэтому не стоит затягивать с переходом на него.



Комментарии

12.09.2022 15:02 stasevich

Описание rest-контроллера
@Tag(
    name = "Пользователи",
    description = "Все методы для работы с пользователями системы",
)
лишняя запятая после description

27.09.2023 01:11 Иван

Это топчик!! Спасибо

Добавить комментарий

×

devmark.ru