Оригинал: This is How I Use Swagger to Design REST APIs Before Starting the Development

Перевод для канала Мы ж программист

Введение

Для разработчика очень важно начать с этапа проектирования, прежде чем приступать к кодированию. То же самое происходит, если вам требуется разработка REST API. В этой статье расскажу, как я использую Swagger (OpenAPI-совместимую платформу спецификаций) для проектирования API и одновременно создания документации по API.

Преимущества создания документации Swagger

1. Обмен спецификациями API: Разработка и создание документации swagger позволит вам поделиться спецификациями API с вашими API-клиентами. Если вы создаете какой-либо REST API, то, вероятно, у вас также будет потребитель этого API, а значит, вам необходимо поделиться спецификациями API. В этом случае, поскольку Swagger следует стандартам Open API, вы можете поделиться файлом Swagger YAML со своим клиентом, чтобы договориться об использовании API.

2. Генерация кода: Существует множество плагинов и инструментов, которые могут генерировать скелетную структуру кода для заданной спецификации Swagger. Таким образом, вы можете генерировать контроллеры, классы DTO и другие классы с помощью YAML-файла swagger.

Генератор кода в редакторе swagger

3. Простота тестирования: Если вы включили в свой код зависимости, связанные со swagger, то Spring или любой другой фреймворк может создать swagger ui для выполнения API после развертывания.

Swagger UI

В этой статье я создам документацию swagger для Student REST API. Проектирование Student API с CRUD-операциями с помощью Swagger (OpenAPI) включает в себя описание эндпоинтов для управления данными студентов. Я пройдусь по каждому шагу и спроектирую эти операции на Swagger.

1. Настройте проект в Swagger

Перейдите на сайт swagger.io и воспользуйтесь либо Swagger Editor, либо SwaggerHub. SwaggerHub обеспечивает совместную работу и контроль версий, а Swagger Editor позволяет писать и визуализировать определение API в режиме реального времени.

В Swagger Editor вы можете определить свой API, используя формат OpenAPI (либо в YAML, либо в JSON). Здесь я буду использовать YAML для наглядности. Когда вы перейдете в редактор Swagger, вы увидите пример YAML для API зоомагазина. Вы можете изменить его или начать с нуля

Редактор Swagger

2. Определите базовую информацию

Начните с определения основных метаданных, таких как название, версия и описание вашего API.

YAML
openapi: 3.0.0
info:
  title: Student API
  description: API for managing students with basic CRUD operations
  version: 1.0.0
servers:
  - url: http://localhost:8080
    description: Development Server

3. Проектирование операций CRUD для Student API

3.1 Создание студента (POST)

На первом шаге нужно описать POST-операция, которая позволяет создать студента.

  • Метод: POST
  • Эндпоинт: /students
  • Тело запроса: Содержит данные о студенте (имя, возраст, email и т.д.)
  • Ответ: Только что созданный студент или ошибки валидации.

Вот как это можно описать в Swagger:

YAML
paths:
  /students:
    post:
      summary: Create a new student
      operationId: createStudent
      requestBody:
        description: Student object to be created
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Student'
      responses:
        '201':
          description: Student successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Student'
        '400':
          description: Invalid input

В этой операции:

  • Схема тела запроса ссылается на объект Student, описанный в секции компонентов (объясню позже).
  • 201 Created – ответ при успешной операции.

3.2 Получение всех студентов (GET)

Чтобы получить список всех студентов, опишем операцию GET.

  • Метод: GET
  • Эндпоинт: /students
  • Ответ: Массив объектов Student.
YAML
    get:
      summary: Get a list of all students
      operationId: getAllStudents
      responses:
        '200':
          description: A list of students
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Student'
        '404':
          description: No students found

Здесь:

  • Ответ содержит массив объектов студентов.
  • 200 OK – возвращается, когда студенты найдены.

3.3 Получение одного студента по ID (GET)

Получим конкретного студента по его ID.

  • Метод: GET
  • Эндпоинт: /students/{id}
  • Параметры: id (параметр пути).
  • Ответ: Объект Student, если найден, либо ошибка 404, если студент не существует.
YAML
  /students/{id}:
    get:
      summary: Get a student by ID
      operationId: getStudentById
      parameters:
        - name: id
          in: path
          required: true
          description: ID of the student to retrieve
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: A student object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Student'
        '404':
          description: Student not found

3.4 Обновление студента по ID (PUT)

Обновим данные существующего студента по его ID.

  • Метод: PUT
  • Эндпоинт: /students/{id}
  • Тело запроса: Содержит данные обновляемого студента.
  • Ответ: Обновленный объект Student, либо ошибка 404, если студент не найден.
YAML
    put:
      summary: Update a student by ID
      operationId: updateStudent
      parameters:
        - name: id
          in: path
          required: true
          description: ID of the student to update
          schema:
            type: integer
            format: int64
      requestBody:
        description: Updated student object
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Student'
      responses:
        '200':
          description: Student successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Student'
        '404':
          description: Student not found

Здесь:

  • Тело запроса содержит обновленные данные о студенте, а ответ – обновленный объект Student.

3.5 Удаление студента по ID (DELETE)

Чтобы удялить студента по его ID, опишем операцию DELETE.

  • Метод: DELETE
  • Эндпоинт: /students/{id}
  • Ответ: Успех или 404, если студент не существует.
YAML
    delete:
      summary: Delete a student by ID
      operationId: deleteStudent
      parameters:
        - name: id
          in: path
          required: true
          description: ID of the student to delete
          schema:
            type: integer
            format: int64
      responses:
        '204':
          description: Student successfully deleted
        '404':
          description: Student not found

4. Определяем компоненты (модели)

Схема объекта Student определяется в секции компонентов и будет использоваться во всех API-операциях.

YAML
components:
  schemas:
    Student:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        age:
          type: integer
        email:
          type: string
        createdAt:
          type: string
          format: date-time
      required:
        - name
        - email

Эта схема описывает структуру объекта Student. Обязательные поля – имя и email.

5. Тестирование и документирование API

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

6. Окончательная структура в Swagger Editor

YAML
openapi: 3.0.0
info:
  title: Student API
  description: API for managing students with basic CRUD operations
  version: 1.0.0
servers:
  - url: http://localhost:8080
    description: Development Server

paths:
  /students:
    post:
      summary: Create a new student
      operationId: createStudent
      requestBody:
        description: Student object to be created
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Student'
      responses:
        '201':
          description: Student successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Student'
        '400':
          description: Invalid input

    get:
      summary: Get a list of all students
      operationId: getAllStudents
      responses:
        '200':
          description: A list of students
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Student'
        '404':
          description: No students found

  /students/{id}:
    get:
      summary: Get a student by ID
      operationId: getStudentById
      parameters:
        - name: id
          in: path
          required: true
          description: ID of the student to retrieve
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: A student object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Student'
        '404':
          description: Student not found

    put:
      summary: Update a student by ID
      operationId: updateStudent
      parameters:
        - name: id
          in: path
          required: true
          description: ID of the student to update
          schema:
            type: integer
            format: int64
      requestBody:
        description: Updated student object
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Student'
      responses:
        '200':
          description: Student successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Student'
        '404':
          description: Student not found

    delete:
      summary: Delete a student by ID
      operationId: deleteStudent
      parameters:
        - name: id
          in: path
          required: true
          description: ID of the student to delete
          schema:
            type: integer
            format: int64
      responses:
        '204':
          description: Student successfully deleted
        '404':
          description: Student not found

components:
  schemas:
    Student:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        age:
          type: integer
        email:
          type: string
        createdAt:
          type: string
          format: date-time
      required:
        - name
        - email

Заключение

Именно так я обычно начинаю разработку любого REST API. Это позволяет мне получить четкое представление о том, что должно быть разработано, и я гарантирую, что такой подход всегда приводит к практически нулевым дефектам, если вы правильно создадите swagger-файл. Я хотел также рассказать о генерации кода, но статья получится слишком длинной, если я это сделаю. Я создам еще одну статью, посвященную только генерации кода. Если вы найдете какие-либо проблемы в этом подходе, не стесняйтесь поправить меня в комментариях.

Удачного кодинга!