Лучшие практики RESTful API

RESTful
Лучшие практики RESTful API

Лучшие практики RESTful API

RESTfulВ настоящее время это самая популярная спецификация API для разработки спецификаций веб-интерфейса. Сделайте интерфейс удобным для чтения и понятным по смыслу. Эта статья покажет вам, как создавать простые для понимания и использования API, с практическими инструкциями API Docker.

URL-дизайн

1.1 Глагол + объект

Его основная идея заключается в том, что все инструкции по обработке данных, отправляемые клиентом, имеют структуру «глагол + объект», например, команда GET /articles, GET — это глагол, а /articles — объект.

Глаголы обычно представляют собой пять HTTP-методов, соответствующих операциям CRUD нашего бизнес-интерфейса. Объект — это ресурс, которым мы хотим управлять, что можно понимать как ресурсно-ориентированный дизайн. Данные, о которых мы заботимся, — это ресурс.

  • ПОЛУЧИТЬ: прочитать ресурс
  • ПОСТ: Новый ресурс
  • ПОСТАВИТЬ: обновить ресурс
  • ИСПРАВЛЕНИЕ: Обновление данных раздела ресурсов
  • УДАЛИТЬ: удалить ресурс

правильный пример

  • GET /zoos: список всех зоопарков
  • POST /zoos: создать новый зоопарк
  • GET /zoos/ID: получить информацию об указанном зоопарке.
  • PUT /zoos/ID: обновить информацию об указанном зоопарке (предоставить всю информацию о зоопарке).
  • PATCH /zoos/ID: обновить информацию об указанном зоопарке (предоставить некоторую информацию о зоопарке).
  • УДАЛИТЬ /zoos/ID: удалить зоопарк
  • GET /zoos/ID/animals: список всех животных в заданном зоопарке.
  • УДАЛИТЬ /zoos/ID/animals/ID: удалить указанное животное в указанном зоопарке

1.2 Покрытие глаголов

Некоторые клиенты могут использовать только два метода GET и POST. Сервер должен принять POST для имитации трех других методов (PUT, PATCH, DELETE).

В это время HTTP-запрос, отправленный клиентом, должен быть добавлен сX-HTTP-Method-Overrideатрибут, который сообщает серверу, какой глагол следует использовать, переопределяя метод POST.

1.3 Объект должен быть существительным

Это URL-адрес API, который является объектом HTTP-глагола, поэтому он должен быть существительным. Например, URL-адрес /books правильный, а следующие URL-адреса не являются существительными, все они имеют неправильное написание.

Пример ошибки:

GET /getAllUsers?name=jl
POST /createUser
POST /deleteUSer

1.4 Существительные во множественном числе

URL — это существительное, так во множественном или единственном числе?

Единого регулирования не существует, но большая часть данных, с которыми мы обычно работаем, представляет собой набор, напримерGET /books, поэтому мы используем комплексные числа.

Единая спецификация, рекомендуется использовать множественные URL-адреса, например, получение книги с id = 2GET /books/2лучше чемGET /book/2.

1.5 Избегайте многоуровневых URL-адресов

Иногда ресурсы, которыми мы хотим управлять, могут иметь несколько уровней, поэтому легко писать многоуровневые URL-адреса, например, получать статьи определенного автора и определенной категории.

GET /authors/2/категории/2 Получить статьи с идентификатором автора = 2 категории = 2

Этот тип URL-адреса не способствует расширению, и его семантика не ясна.

Лучшим способом является то, что все уровни, кроме первого, выражаются через строки запроса.

Правильный путь:GET /authors/12?categories=2

Запрос опубликованных статей

Неправильное написание: GET /artichels/published

Правильная формулировка :? Get / Artichels опубликовано = True

Фильтрация информации (фильтрация)

Код состояния Если количество записей велико, сервер не может вернуть их все пользователю. API должен предоставлять параметры для фильтрации возвращаемых результатов.

Ниже приведены некоторые общие параметры.

  • ?limit=10: Укажите количество возвращаемых записей.
  • ?offset=10: указывает начальную позицию возвращаемой записи.
  • ?page=2&per_page=100: укажите количество страниц и количество записей на странице.
  • ?sortby=name&order=asc: указывает, по какому атрибуту возвращаемые результаты сортируются, и порядок сортировки.
  • Animal_Type_ID = 1: Укажите критерии фильтра

Параметры предназначены для обеспечения избыточности, что позволяет время от времени повторять пути API и параметры URL. Например, GET /zoo/ID/animals имеет то же значение, что и GET /animals?zoo-id=ID. Последнее рекомендуется, чтобы избежать многоуровневых URL-адресов.

2.1 Коды состояния должны быть точными

На запросы клиентов и сервисные запросы необходимо отвечать, включая коды состояния HTTP и данные.

Код состояния HTTP представляет собой трехзначное число, разделенное на пять категорий.

  • 1xx: связанная информация
  • 2xx: успешная операция
  • 3xx: перенаправление
  • 4xx: ошибка клиента
  • 5xx: ошибка сервера

2.2 Коды состояния 2xx

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

  • GET: 200 OK
  • POST: 201 Created
  • PUT: 200 OK
  • PATCH: 200 OK
  • DELETE: 204 No Content

2.3 Коды состояния 4xx

Код состояния 4xx указывает на ошибку клиента, которая в основном включает следующие типы.

  • 400 Bad Request: сервер не понимает запрос клиента и не выполняет никакой обработки.
  • 401 Unauthorized: пользователь не предоставил учетные данные для аутентификации или не прошел аутентификацию.
  • 403 Запрещено: пользователь прошел проверку подлинности, но не имеет необходимых разрешений для доступа к ресурсу.
  • 404 Not Found: запрошенный ресурс не существует или недоступен.
  • 405 Метод не разрешен: пользователь прошел аутентификацию, но используемый метод HTTP не входит в его полномочия.
  • 410 Gone: запрошенный ресурс из адресной передачи больше недоступен.
  • 415 Неподдерживаемый тип носителя: формат возврата, запрошенный клиентом, не поддерживается. Например, API может возвращать только формат JSON, но клиент запрашивает возврат формата XML.
  • 422 Unprocessable Entity: вложение, загруженное клиентом, не может быть обработано, что приводит к сбою запроса.
  • 429 Слишком много запросов: количество клиентских запросов превысило лимит.

2.4 Коды состояния 5xx

Коды состояния 5xx указывают на ошибки сервера. Как правило, API не раскрывает пользователю сведения о сервере, поэтому достаточно только двух кодов состояния.

  • 500 Internal Server Error: запрос клиента действителен, но при его обработке сервером произошла непредвиденная ошибка.
  • 503 Служба недоступна: сервер не может обработать запрос, обычно используемый для статуса обслуживания веб-сайта.

ответ сервера

3.1 Не возвращайте обычный текст

Формат данных, возвращаемый API, должен быть не простым текстом, а объектом JSON, поскольку таким образом могут быть возвращены стандартные структурированные данные. Поэтому для свойства Content-Type заголовка HTTP, возвращаемого сервером, должно быть установлено значение application/json .

Когда клиент запрашивает, он также должен четко сообщать серверу, что формат JSON приемлем, то есть атрибут ACCEPT HTTP-заголовка запроса также должен быть установлен в application/json. Ниже приведен пример.

3.2 При возникновении ошибки не возвращайте код состояния 200

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

Примеры ошибок:

HTTP/1.1 200 OK
ConteNTP-Type: application/json

{
	"status": "fail",
	"msg": "错误"
}

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

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

Правильный путь:

HTTP/1.1 400 Bad Request
ConteNTP-Type: application/json

{
	"status": "fail",
	"msg": "错误"
}

разбор спецификации docker RESTful

Далее мы анализируем использование docker api для restful, чтобы помочь нам разумно проектировать на практике.

URL-адрес документации докера:docs.docker.com/engine/APi / ...

4.1 GET для получения списка контейнеров

GET /v1.19/containers/json?all=1&before=8dfafdbc3a40&size=1 HTTP/1.1

Отфильтровать данные контейнера по всем=1&before=8dfafdbc3a40&size=1

4.2 GET, чтобы получить указанный идентификатор или имя контейнера

GET /containers/(id or name)/json

GET /v1.19/containers/4fa6e0f0c678/json HTTP/1.1

4.3 GET для получения процесса контейнера

GET /v1.19/containers/4fa6e0f0c678/top HTTP/1.1

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

GET /v1.19/containers/4fa6e0f0c678/top?ps_args=aux HTTP/1.1

данные возвращены

HTTP/1.1 200 OK
Content-Type: application/json

{
  "Titles" : [
    "USER","PID","%CPU","%MEM","VSZ","RSS","TTY","STAT","START","TIME","COMMAND"
  ]
  "Processes" : [
    [
      "root","13642","0.0","0.1","18172","3184","pts/0","Ss","17:03","0:00","/bin/bash"
    ],
    [
      "root","13895","0.0","0.0","4348","692","pts/0","S+","17:15","0:00","sleep 10"
    ]
  ],
}

4.4 Пост для создания контейнера

POST /containers/create

POST /v1.19/containers/create HTTP/1.1
Content-Type: application/json
Content-Length: 12345

{
       "Hostname": "",
       "Domainname": "",
       "User": "",
       "AttachStdin": false,
       "AttachStdout": true,
       "AttachStderr": true,
       "Tty": false,
       "OpenStdin": false,
       "StdinOnce": false,
       "Env": [
               "FOO=bar",
               "BAZ=quux"
       ],
       "Cmd": [
               "date"
       ],
       "Entrypoint": null,
       "Image": "ubuntu",
       "Labels": {
               "com.example.vendor": "Acme",
               "com.example.license": "GPL",
               "com.example.version": "1.0"
       },
       "Volumes": {
         "/volumes/data": {}
       }
   
  }

4.5 УДАЛИТЬ удалить контейнер

Удалить контейнер по идентификатору контейнера, v — запрос на удаление томов контейнера

DELETE /v1.19/containers/16253994b7c4?v=1 HTTP/1.1

Query parameters:

  • v– 1/True/true или 0/False/false, удаление томов, связанных с контейнером.По умолчаниюfalse.
  • force - 1/True/true or 0/False/false, Kill then remove the container. Default false.
  • link - 1/True/true or 0/False/false, Remove the specified link associated to the container. Default false.