RESTful API спецификаций Лучшие практики проектирования

Spring Boot

RESTfulВ настоящее время это популярная спецификация дизайна пути интерфейса. Основанная на HTTP, она обычно определяется в JSON. Различные HttpMethods используются для определения действий ресурсов соответствующего интерфейса, таких как: добавить (POST), удалить (DELETE), обновить ( PUT, PATCH), запрос (GET) и т. д.

путь дизайн

существуетRESTfulВ спецификации дизайна каждый интерфейс рассматривается как запрос ресурса. Давайте посмотрим на структуру пути API для каждого типа ресурса.

路径设计из注意事项Следующее:

  • Используйте множественное число для имен ресурсов
  • название ресурса существительное
  • В пути нет специальных символов
  • Избегайте многоуровневых URL-адресов

Добавить ресурсы

метод запроса пример пути
POST api.yuqiyu.com/v1/users

Добавить использование ресурсовPOSTспособ определить интерфейс, добавить данные ресурса черезRequestBodyметод передается следующим образом:

curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
    "name": "恒宇少年", 
    "age": 25, 
    "address": "山东济南"
}'

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

{
  "id" : 1,
  "name" : "恒宇少年"
}

Другие интерфейсы данных для управления ресурсом через возвращенный уникальный идентификатор.

удалить ресурс

метод запроса пример пути Примечание
DELETE api.yuqiyu.com/v1/users Массовое удаление ресурсов
DELETE API с rest.com/V1/users/{i… удалить один ресурс

удалить использование ресурсовDELETEспособ определения интерфейса.

  • Удалить один ресурс на основе значения первичного ключа

    curl -X DELETE https://api.yuqiyu.com/v1/users/1
    

    ресурс主键值Передается интерфейсу путем пути.

  • удалить несколько ресурсов

    curl -X DELETE -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
        "userIds": [
            1, 
            2, 
            3
        ]
    }'
    

    Пройдено при удалении нескольких ресурсовRequestBodyВ приведенном выше примере в качестве условия удаления используется набор значений первичного ключа ресурса. Конечно, другие элементы ресурса также могут использоваться в качестве условия удаления, например:name

Обновление ресурсов

метод запроса пример пути Примечание
PUT API с rest.com/V1/users/{i… обновить один ресурсвсеэлемент
PATCH API с rest.com/V1/users/{i… обновить один ресурсчастьэлемент

Используется при обновлении данных ресурсаPUTЕсть все более и более распространенные способы, а именно:

curl -X PUT -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users/1 -d '{
    "name": "恒宇少年", 
    "age": 25, 
    "address": "山东济南"
}'

Запрос одного ресурса

метод запроса пример пути Примечание
GET API с rest.com/V1/users/{i… Запрос одного ресурса
GET API с rest.com/V1/users? Неоднозначно идентифицированные ресурсы запроса
  • Уникально идентифицирует и запрашивает один ресурс

    curl https://api.yuqiyu.com/v1/users/1
    

    При запросе ресурсов по уникальному идентификатору значение идентификатора передается методом пути, что отражает иерархическую связь.

  • Запрос одного ресурса с неуникальным идентификатором

    curl https://api.yuqiyu.com/v1/users?name=恒宇少年
    

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

Ресурсы запроса пейджинга

метод запроса пример пути
GET API с rest.com/V1/users?

При подкачке ресурсов запроса нам обычно нужно передать два параметра в качестве условия подкачки:pageПредставляет номер страницы текущего пейджинга,sizeОн представляет собой количество ресурсов, запрошенных на страницу.

curl https://api.yuqiyu.com/v1/users?page=1&size=20

Если вам нужно передать условия запроса при подкачке, вы можете продолжить добавлять параметры запроса.

https://api.yuqiyu.com/v1/users?page=1&size=20&name=恒宇少年

Ресурс действий

Иногда нам нужно изменить содержимое элемента ресурса в действии, например, сбросить пароль.

метод запроса пример пути Примечание
POST API с rest.com/V1/users/{i… -

Уникальный идентификатор пользователя передается в пути запроса, а измененный пароль передается черезRequestBodyметод передается следующим образом:

curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users/1/actions/forget-password -d '{
    "newPassword": "123456"
}'

номер версии

Номер версии используется для различенияApiНовые и старые стандарты интерфейса, самые популярные из них接口路径,头信息Оба пути передаются.

  • путь интерфейса

    При развертывании интерфейса мы договариваемся об использовании разных версий запросаHTTP代理Перенаправить на соответствующую версию интерфейсного шлюза, обычно используемый прокси-сервер переадресации запросов, например, использовать:NginxЖдать.

    У этого способа есть недостаток, если несколько версий одновременно пересылают запросы к одной и той же.网关, это приведет к тому, что конкретная версия запроса не будет перенаправлена, мы посещаемv1может быть направленоv2, это не тот результат, которого мы ожидаем, конечно, он может быть网关Добавьте слой перехватчика для управления переадресацией путем извлечения номера версии пути к работе.

    # v1版本的请求
    curl https://api.yuqiyu.com/v1/users/1
    # v2版本的请求
    curl https://api.yuqiyu.com/v2/users/1
    
  • информация заголовка

    Мы можем передать доступную версию интерфейса черезHttpHeaderспособ передачи, в网关Контролировать переадресацию на соответствующую версию сервиса в соответствии с извлеченной информацией заголовка,Таким образом, представление путей к ресурсам не изменится из-за разных версий..

    # v1版本的请求
    curl -H 'Accept-Version:v1' https://api.yuqiyu.com/users/1
    # v2版本的请求
    curl -H 'Access-Version: v2' https://api.yuqiyu.com/users/1
    

    Две версии запроса могут иметь разные параметры запроса и возвращаемые значения, но путь запроса одинаков.

    заголовок версииKeyЕго можно определить в соответствии с вашей собственной ситуацией, рекомендуется использоватьAccpetформа, см.Versioning REST Services.

код состояния

существуетRESTfulВ рамках технического задания нам необходимо полностьюHttpStatusКод состояния запроса используется для оценки состояния отправки запроса и того, является ли запрос действительным или нет.HttpStatusКоды состояния следующие:

код состояния Сцена возникновения
200 запрос выполнен
201 Новый ресурс успешно создан
204 ничего не вернулось
400 Переданный параметр имеет неправильный формат
401 нет доступа
403 Ресурсы защищены
404 Неверный путь доступа
405 Неверный метод доступа, запрос GET использует метод POST для доступа
410 Адрес был передан и недоступен
415 Формат, возвращаемый интерфейсом, должен быть неверным, например: клиенту нужен формат JSON, а интерфейс возвращает XML
429 Количество клиентских запросов превышает лимит
500 Системное исключение возникает на доступном интерфейсе
503 Служба недоступна и, как правило, находится на техническом обслуживании.

Нам нужно сделать разные отзывы для разных кодов состояния.Давайте сначала рассмотрим общий.参数异常Способ проектирования ответа на ошибку:

# 发起请求
curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
    "name": "", 
    "age": 25, 
    "address": "山东济南"
}'
# 响应状态
HttpStatus 200
# 响应内容
{
    "code": "400", 
    "message": "用户名必填."
}

На стороне сервера мы можем контролировать фиксированный формат возврата различных кодов состояния и разных исключений и не должны возвращать все запросы исключений.200, а затем, соответственно, вернуть ошибку правильным образом:

# 发起请求
curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
    "name": "", 
    "age": 25, 
    "address": "山东济南"
}'
# 响应状态
HttpStatus 400
# 响应内容
{
    "error": "Bad Request", 
    "message": "用户名必填."
}

формат ответа

Формат ответа интерфейса должен быть统一.

Внешний формат возвращаемого значения интерфейса для каждого успешного запроса должен быть унифицирован, и сервер может использовать метод объекта для универсального возврата.

Следующее:

/**
 * Api统一响应实体
 * {@link #data } 每个不同的接口响应的数据内容
 * {@link #code } 业务异常响应状态码
 * {@link #errorMsg} 业务异常消息内容
 * {@link #timestamp} 接口响应的时间戳
 *
 * @author 恒宇少年 - 于起宇
 */
@Data
public class ApiResponse<T> implements Serializable {
    private T data;
    private String code;
    private String errorMsg;
    private Long timestamp;
}
  • data

    из-за каждогоAPIТип данных ответа несовместим, поэтому возвращается универсальный тип, использованный выше.dataЛюбой тип данных может быть возвращен.

  • code

    Код исключения бизнес-логики, например: USER_NOT_FOUND (пользователь не существует) Это контракт интерфейса

  • errorMsg

    соответствоватьcodeСтоит описать.

  • timestamp

    Временная метка ответа на запрос

Суммировать

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