Skip to content

Latest commit

 

History

History
392 lines (371 loc) · 12.8 KB

cases.markdown

File metadata and controls

392 lines (371 loc) · 12.8 KB

API Design Cases

Содержание

Кейсы

Именование пути запроса

  • Не пишите действие в названии пути, о котором говорит HTTP method (create, update, delete и тд). Используйте HTTP методы для CRUD операций. В этом и есть их смысл.
    • GET: получение данных о ресурсах.
    • POST: создание новых ресурсов и подресурсов.
    • PUT: обновление существующих ресурсов.
    • PATCH: обновляет только определённые поля существующих ресурсов.
    • DELETE: удаляет ресурсы.
    Плохо Хорошо
    POST /courses/create - Создать новый курс POST /courses - Создать новый курс
  • Используйте kebab-case для URL
    Плохо Хорошо
    /systemOrders
    /system_orders
    /system-orders
  • Используйте простой порядковый номер для версий и всегда указывайте его на самом верхнем уровне.
    Плохо Хорошо
    http://myproject.com/v1/shops/3/products
  • Используйте множественное число для коллекций
    Плохо Хорошо
    GET /user
    GET /User
    GET /users
  • URL должен начинаться с коллекции и заканчиваться идентификатором
    Плохо Хорошо
    GET /shops/{shopId}/category/{categoryId}/price
    Такой вариант плох тем, что указывает на свойство вместо ресурса
    GET /shops/{shopId}/ или GET /category/{categoryId}
  • Не используйте глаголы в URL ресурсов. Вместо этого пользуйтесь HTTP методами для описания операций.
    Плохо Хорошо
    POST /updateuser/{userId}
    GET /getusers
    PUT /user/{userId}
  • Пользуйтесь глаголами в URL операций.
    Плохо Хорошо
    POST /alerts/245743/resend
    Помните, что resend не является CRUD операцией. Наоборот, это функция, которая выполняет определённое действие на сервере.

Параметры запроса

  • Не декларируйте объекты в параметрах запроса

    Плохо Хорошо
    parameters:
          - name: q
            in: query
            required: true
            schema:
              type: object
              properties:
                name:
                  type: string
    parameters:
          - name: q
            in: query
            required: true
            schema:
              type: string

    Если все же необходим объект, то объявите его в моделях и ссылайтесь на данный объект

    parameters:
          - name: q
            in: query
            required: true
            schema:
              $ref: "models.yaml#/components/schemas/Report"

    Можно вынести отдельно параметры для дальнейшего переиспользования и ссылаться на объявленные параметры

    parameters:
          - $ref: "models.yaml#/components/parameters/Param1"

Тело запроса

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

    Плохо Хорошо
    requestBody: 
      required: true
      content:
        application/json: 
          schema:
            type: object
            properties:
              name:
                type: string
              id:
                type: string
    requestBody: 
      required: true
      content:
        application/json: 
          schema:
            $ref: "models.yaml#/components/schemas/RecalculateOrderRequest"
    requestBody: 
      required: true
      content:
        application/json: 
          schema:
            type: array
            items:
              $ref: "models.yaml#/components/schemas/RecalculateOrderRequest"

Ответ

  • Аналогично телу запроса. Всегда ставьте ссылки на модели, не дакларируйте объекты в ответе.

    Плохо Хорошо
    responses:
        '200':
          description: Все ок
          $ref: "models.yaml#/components/schemas/Response" 
    responses:
        '200':
          description: Все ок
          content:
            application/json: 
              schema:
                type: object
                properties:
                  name:
                    type: string
                  id:
                    type: string
    responses:
        '200':
          description: Все ок
          content:
            application/json: 
              schema: $ref: "models.yaml#/components/schemas/Response" 
    
  • Указывайте количество ресурсов в ответе на запрос

    Плохо Хорошо
    {
      users: [], 
      offset: 0
    }
    {
      users: [], 
      offset: 0,
      total: 34
    }

Общие моменты

  • Пишите описание к методам API и моделям, используя свойство description и summary. Описывайте там задачу которую решает метод или свойство.

    Плохо Хорошо
    paths:
    
      /search:
        get:
          summary: Поиск с постраничной пагинацией    
          parameters:
            - name: query
              in: query
              required: true
              schema:
                type: string
            - $ref: "../../common/parameters.yaml#/components/Limit"
            - $ref: "../../common/parameters.yaml#/components/Offset"
          responses:
            "200":
              description: >
                Успешный ответ.  
              content:
                "application/json":
                  schema:
                    type: array
                    items:
                      $ref: "models.yaml#/components/schemas/SearchItem"
            "500":
              description: Что-то сломалось на сервере.
              content:
                "application/json":
                  schema:
                    $ref: "../../common/errors.yaml#/components/schemas/CommonError"
    paths:
    
      /search:
        get:
          summary: Поиск с постраничной пагинацией
          description: >
            Выполняет поиск по запросу заданному в `query`.
            Пагинация работает следующим образом:
            -> Первый запрос:
              query = "Яблоки"
              limit = 10
              offset = 0
            Сервер вернул 10 элементов
            -> Второй запрос:
            query = "Яблоки"
            limit = 10
            offset = 10
            Сервер вернул 5 элементов --> нашлось только 15 элементов. Пагинация закончилась. 
            Каждый параметр отдельно описан.      
          parameters:
            - name: query
              in: query
              description: Содержит запрос по которому будет выполняться поиск
              required: true
              schema:
                type: string
            - $ref: "../../common/parameters.yaml#/components/Limit"
            - $ref: "../../common/parameters.yaml#/components/Offset"
          responses:
            "200":
              description: >
                Успешный ответ. 
                **ВАЖНО**
                Может содержать пустой массив -- тем самым обозначать то, что пагинация закончилась.
                Так же, вам нужно будет самим уточнить у вашего бэка какие могут быть ошибки и как их нужно обрабатывать. 
              content:
                "application/json":
                  schema:
                    type: array
                    items:
                      $ref: "models.yaml#/components/schemas/SearchItem"
            "500":
              description: Что-то сломалось на сервере.
              content:
                "application/json":
                  schema:
                    $ref: "../../common/errors.yaml#/components/schemas/CommonError"
  • Используйте camelCase для JSON свойств

    Плохо Хорошо
    {
      user_name: "Васька Петров",
      user_id: "1"
    }
    {
      userName: "Васька Петров",
      userId: "1"
    }