Поиск…


замечания

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

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

Обзор REST

REST означает RE presentational S tate T ransfer и был придуман Роем ​​Филдингом в его докторской диссертации « Архитектурные стили» и «Дизайн сетевых архитектур» . В нем он определяет конкретные архитектурные принципы, такие как:

  • Адресные ресурсы: ключевая абстракция информации и данных в REST - это ресурс, и каждый ресурс должен быть адресуемым через URI.

  • Единый, ограниченный интерфейс: использование небольшого набора четко определенных методов для управления нашими ресурсами.

  • Ориентация на представление: ресурс, на который ссылается один URI, может иметь разные форматы, а разные платформы нуждаются в разных форматах, например, браузеру нужен HTML, JavaScript нуждается в JSON и Java-приложениях, возможно, нужны XML, JSON, CSV, текст и т. Д. Поэтому мы взаимодействуем с сервисами используя представление этой службы.

  • Общаться без гражданства: приложения без гражданства легче масштабируются.

  • Hypermedia как механизм состояния приложения: пусть наши данные форматируют переход состояния состояния в наших приложениях.

Набор этих архитектурных принципов называется REST. Концепции REST основаны на концепции HTTP. Рой Филдинг, который дал REST нам, также является одним из авторов спецификаций HTTP.

Веб-сервисы и веб-службы RESTful - это услуги, которые доступны для доступа в Интернет для доступа к Интернету. Они онлайн-апи, которые мы можем позвонить из нашего кода. Существует два типа веб-сервисов SOAP и REST «Большие» веб-сервисы.

Веб-службы RESTful : веб-сервисы, написанные с применением архитектурных концепций REST, называются веб-службами RESTful, которые фокусируются на системных ресурсах и как состояние ресурса может передаваться по протоколу HTTP различным клиентам.

Этот документ ориентирован исключительно на веб-сервисы RESTful, поэтому мы не будем вдаваться в подробности SOAP WS.

При разработке веб-сервисов RESTful нет строгих правил

  • Нет стандартного протокола
  • Нет стандарта канала связи
  • Нет стандартного определения услуги

Но SOAP имеет строгие правила для всех этих. Все веб-службы SOAP соответствуют спецификации SOAP, которая определяет, что должны делать все веб-службы SOAP. Эта спецификация разрабатывается и управляется комитетом, и если SOAP WS не следует ни одному правилу, то по определению это не SOAP.

Концепции веб-служб RESTful

Существует несколько рекомендаций, которые необходимо учитывать при разработке / разработке RESTful api:

  1. Ресурсные местоположения / URI
  2. Правильное использование HTTP-методов
  3. HATEOAS (Hypermedia как двигатель состояния приложения)

Основной подход при разработке API RESTful должен заключаться в том, чтобы сделать API «как RESTful» возможным.

REST через HTTP

REST - это протокол-агностическая архитектура, предложенная Роем ​​Филдингом в его диссертации (глава 5 - презентация REST), которая обобщает проверенную концепцию веб-браузеров как клиентов, чтобы разделить клиентов в распределенной системе с серверов.

Чтобы сервис или API был RESTful, он должен придерживаться заданных ограничений, таких как:

  • Клиент-сервер
  • Stateless
  • Cacheable
  • Многослойная система
  • Равномерный интерфейс
    • Определение ресурсов
    • Представление ресурсов
    • Самоописательные сообщения
    • гипермедиа

Помимо ограничений, упомянутых в диссертации Филдинга, в своем блоге REST API должен быть основан на гипертексте , Филдинг пояснил, что просто вызов службы через HTTP не делает ее RESTful . Поэтому служба должна также соблюдать дальнейшие правила, которые суммируются следующим образом:

  • API должен придерживаться и не нарушать базовый протокол. Хотя REST чаще всего используется по протоколу HTTP, он не ограничивается этим протоколом.

  • Сильный акцент на ресурсы и их представление через медиа-типы.

  • Клиенты не должны иметь начальных знаний или предположений о доступных ресурсах или их возвращенном состоянии ( «типизированный» ресурс ) в API, но изучать их «на лету» через выданные запросы и анализировать ответы. Это дает серверу возможность легко перемещаться или переименовывать ресурсы, не нарушая реализацию клиента.

Модель зрелости Ричардсона

Модель зрелости Richardson - это способ применения ограничений REST по HTTP для получения веб-сервисов RESTful.

Леонард Ричардсон разделил приложения на эти 4 слоя:

  • Уровень 0: использование HTTP для транспорта
  • Уровень 1: использование URL для идентификации ресурсов
  • Уровень 2: использование HTTP-глаголов и статусов для взаимодействия
  • Уровень 3: использование HATEOAS

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

Обратите также внимание, что с учетом ограничений Fielding API эффективно RESTful только после реализации 3-го уровня RMM .


HTTP-запросы и ответы

HTTP-запрос:

  • Глагол (метод aka), большую часть времени один из GET , POST , PUT , DELETE или PATCH
  • URL-адрес
  • Заголовки (пары с ключом)
  • Необязательно тело (aka полезная нагрузка, данные)

Ответ HTTP:

Характеристики глаголов HTTP:

  • Глаголы, имеющие тело: POST , PUT , PATCH
  • Глаголы, которые должны быть безопасными (то есть, которые не должны изменять ресурсы): GET
  • Глаголы, которые должны быть идемпотентными (то есть, которые не должны влиять на ресурсы снова при многократном запуске): GET (nullipotent), PUT , DELETE
        body  safe  idempotent
GET      ✗     ✔     ✔
POST     ✔     ✗     ✗
PUT      ✔     ✗     ✔
DELETE   ✗     ✗     ✔
PATCH    ✔     ✗     ✗

Следовательно , HTTP-глаголы можно сравнить с функциями CRUD :

Обратите внимание, что запрос PUT просит клиентов отправить весь ресурс с обновленными значениями. Чтобы частично обновить ресурс, можно использовать глагол PATCH (см. Как частично обновлять ресурс? ).

Обычные статусы HTTP-ответа

успех

Перенаправление

  • 304 (НЕ МОДИФИЦИРОВАН) : клиент может использовать кэшированную версию, имеющуюся у запрашиваемого ресурса

Ошибки клиента

  • 401 (UNAUTHORIZED) : анонимный запрос обращается к защищенному API
  • 403 (FORBIDDEN) : аутентифицированный запрос не имеет достаточных прав для доступа к защищенному API
  • 404 (НЕ НАЙДЕНО) : ресурс не найден
  • 409 (КОНФЛИКТ) : состояние ресурсов в конфликте (например, пользователь пытается создать учетную запись с уже зарегистрированным письмом)
  • 410 (GONE) : то же, что и 404, но ресурс существует
  • 412 (PRECONDITION FAILED) : запрос пытается изменить ресурс, находящийся в неожиданном состоянии
  • 422 (НЕПРЕРЫВНАЯ ЭНЕРГИЯ) : запрос полезной нагрузки синтаксически действителен, но семантически ошибочен (например, требуемое поле, которое не оценивалось)
  • 423 (LOCKED) : ресурс заблокирован
  • 424 (FAILED DEPENDENCY) : запрошенное действие зависело от другого действия, которое не выполнено
  • 429 (СЛИШКОМ МНОГИЕ ЗАПРОСЫ) : пользователь отправил слишком много запросов за определенное количество времени
  • В противном случае: 400 (БЕСПЛАТНЫЙ ЗАПРОС)

Ошибки сервера

Заметки

Ничто не мешает вам добавлять тело к ошибочным ответам, чтобы сделать отказ более понятным для клиентов. Например, 422 (НЕПРЕРЫВНЫЙ ENTITY) немного расплывчатый: орган ответа должен указать причину, по которой объект не может быть обработан.


HATEOAS

Каждый ресурс должен предоставлять гипермедиа ресурсам, с которыми он связан. Ссылка, по крайней мере, состоит из:

  • rel (для отн Ц И А Ц, иначе название): описывает связь между основным ресурсом и связанным одного (ов)
  • A href : URL-адрес, предназначенный для связанных ресурсов (-ов)

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

Cormac Mulhall объясняет, что клиент должен решить, какой HTTP-глагол использовать на основе того, что он пытается сделать . Если вы сомневаетесь, документация API должна в любом случае помочь вам понять доступные взаимодействия со всеми гипермедиа.


Типы носителей

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

Хотя application/json и application/xml являются довольно популярными медиа-типами, они не содержат много семантики. Они просто описывают общий синтаксис, используемый в документе. Более специализированные медиа-типы, поддерживающие требования HATEOAS, должны использоваться (или распространяться через типы медиа-производителей ), например:

Клиент сообщает серверу, какие типы носителей он понимает, добавив заголовок Accept в свой запрос, например:

Accept: application/hal+json

Если сервер не может создать запрошенный ресурс в таком представлении, он возвращает 406 (НЕ ПРИНИМАЕТСЯ) . В противном случае он добавляет тип медиа в заголовок Content-Type ответа, содержащего представленный ресурс, например:

Content-Type: application/hal+json

Безгосударственный> stateful

Зачем?

Сервер с состоянием подразумевает, что сеансы клиентов хранятся в локальном хранилище server-instance (почти всегда в сеансах веб-сервера). Это начинает возникать при попытке масштабирования по горизонтали : если вы скрываете несколько экземпляров сервера за балансировщиком нагрузки, если один клиент сначала отправляется в экземпляр # 1 при входе в систему, а затем в экземпляр # 2 при извлечении защищенного ресурса, например , то второй экземпляр обработает запрос как анонимный, так как клиентский сеанс хранится локально в экземпляре # 1 .

Решения были решены для решения этой проблемы (например, путем настройки репликации сеанса и / или липкого сеанса ), но архитектура REST предлагает другой подход: просто не делайте серверным с точки зрения состояния, сделайте его безстоящим . По словам Филдинга :

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

Другими словами, запрос должен обрабатываться точно так же, независимо от того, отправлен ли он экземпляру # 1 или экземпляру # 2 . Вот почему приложения без гражданства считаются более легкими для масштабирования .

Как?

Общим подходом является аутентификация на основе токенов , особенно с модными веб-маркерами JSON . Обратите внимание, что JWT все еще имеет некоторые проблемы, особенно в отношении недействительности и автоматического продления срока действия (т. Е. Функция « запомнить меня» ).

Боковые заметки

Использование файлов cookie или заголовков (или что-либо еще) не имеет никакого отношения к тому, является ли сервер состоятельным или неактивным: это только носители, которые здесь используются для переноса токенов (идентификатор сеанса для серверов с поддержкой состояния, JWT и т. Д.), Не более того.

Когда API RESTful используется только браузерами, ( HttpOnly и безопасные ) файлы cookie могут быть весьма удобными, поскольку браузеры автоматически присоединяют их к исходящим запросам. Стоит отметить, что если вы выберете куки-файлы, будьте в курсе CSRF (хороший способ предотвратить его - заставить клиентов генерировать и отправлять одно и то же уникальное секретное значение как в cookie, так и в пользовательский HTTP-заголовок ).


API-интерфейс кэширования с условными запросами

С заголовком Last-Modified

Сервер может предоставить заголовок Last-Modified для ответов, содержащих ресурсы, которые можно кэшировать. Затем клиенты должны сохранить эту дату вместе с ресурсом.

Теперь каждый раз, когда клиенты запрашивают API для чтения ресурса, они могут добавлять к своим запросам заголовок If-Modified-Since содержащий последнюю дату последней Last-Modified они получили и сохранили. Затем сервер должен сравнить заголовок запроса и фактическую последнюю измененную дату ресурса. Если они равны, сервер возвращает 304 (NOT MODIFIED) с пустым телом: запрашивающий клиент должен использовать текущий кешированный ресурс, который у него есть.

Кроме того, когда клиенты запрашивают API для обновления ресурса (т. Е. С помощью небезопасного глагола), они могут добавить заголовок If-Unmodified-Since . Это помогает справиться с условиями гонки: если заголовок и фактическая последняя измененная дата отличаются, сервер возвращает 412 (ПРЕССИОНАЦИЯ НЕИСПРАВНО) . Затем клиент должен прочитать новое состояние ресурса перед повторной попыткой изменить ресурс.

С заголовком ETag

ETag (тег объекта) является идентификатором для конкретного состояния ресурса. Это может быть хеш MD5 ресурса для сильной проверки или идентификатор домена для слабой проверки .

В принципе, процесс такой же, как и с заголовком Last-Modified : сервер предоставляет заголовок ETag для ответов, содержащих ресурсы, которые можно кэшировать, и клиенты должны затем хранить этот идентификатор вместе с ресурсом.

Затем клиенты предоставляют заголовок If-None-Match когда они хотят прочитать ресурс, содержащий последний ETag, который они получили и сохранили. Теперь сервер может вернуть 304 (NOT MODIFIED), если заголовок соответствует фактическому ETag ресурса.

Опять же, клиенты могут предоставить заголовок If-Match когда они хотят изменить ресурс, и сервер должен вернуть 412 (PRECONDITION FAILED), если предоставленный ETag не соответствует фактическому.

Дополнительные примечания

ETag> дата

Если клиенты предоставляют как даты, так и ETag в своих запросах, дата должна быть проигнорирована. Из RFC 7232 ( здесь и здесь ):

Получатель ДОЛЖЕН игнорировать If-Modified-Since / If-Unmodified-Since если запрос содержит поле заголовка If-None-Match / If-Match ; условие в If-None-Match / If-Match считается более точной заменой условия в If-Modified-Since / If-Unmodified-Since , и эти два объединяются только для взаимодействия со старыми посредниками которые могут не реализовывать If-None-Match / If-Match .

Неглубокие ETags

Кроме того, хотя совершенно очевидно, что последние измененные даты сохраняются вместе с ресурсами на стороне сервера, в ETag доступны несколько подходов .

Обычный подход заключается в реализации неглубоких ETags: сервер обрабатывает запрос так, как если бы не были указаны условные заголовки, но только в самом конце, он генерирует ETag ответа, который он собирается вернуть (например, путем его хэширования), и сравнивает он с предоставленным. Это относительно просто реализовать, поскольку нужен только HTTP-перехватчик (и многие реализации уже существуют в зависимости от сервера). При этом стоит отметить, что этот подход позволит сэкономить пропускную способность, но не производительность сервера :

Более глубокая реализация механизма ETag потенциально может обеспечить гораздо большие преимущества - например, обслуживание некоторых запросов из кеша и отсутствие необходимости выполнять вычисления вообще, но реализация, безусловно, будет не такой простой и не подталкивающей, как мелкий подход описанных здесь.


Обычные подводные камни

Почему я не должен помещать глаголы в URL?

HTTP не RPC : то, что делает HTTP, существенно отличающееся от RPC, заключается в том, что запросы направлены на ресурсы . В конце концов, URL-адрес обозначает Uniform Resource Locator, а URL-адрес - URI : Uniform Resource Idenfitier. URL-адрес предназначен для ресурса, с которым вы хотите иметь дело , метод HTTP указывает, что вы хотите с ним делать . Методы HTTP также известны как глаголы : глаголы в URL-адресах тогда не имеют смысла. Обратите внимание, что отношения HATEOAS не должны содержать глаголов, поскольку ссылки также нацелены на ресурсы.

Как частично обновить ресурс?

Поскольку запросы PUT требуют от клиентов отправить весь ресурс с обновленными значениями, PUT /users/123 не могут использоваться для простого обновления электронной почты пользователя, например. Как объяснил Уильям Дюран в « Пожалуйста». Не патчи как идиот. , доступны несколько REST-совместимых решений:

  • Выделите свойства ресурса и используйте метод PUT для отправки обновленного значения, поскольку спецификация PUT заявляет, что частичные обновления содержимого возможны путем ориентации отдельно идентифицированного ресурса с состоянием, которое перекрывает часть более крупного ресурса :
PUT https://example.com/api/v1.2/users/123/email
body:
  new.email@example.com
  • Используйте запрос PATCH , содержащий набор инструкций, описывающих, как должен быть изменен ресурс (например, после исправления JSON ):
PATCH https://example.com/api/v1.2/users/123
body:
  [
    { "op": "replace", "path": "/email", "value": "new.email@example.com" }
  ]
PATCH https://example.com/api/v1.2/users/123
body:
  {
    "email": "new.email@example.com"
  }

Что относительно действий, которые не вписываются в мир операций CRUD?

Цитирование Vinay Sahni в передовой практике для разработки прагматичного API RESTful :

Здесь все может стать нечетким. Существует ряд подходов:

  1. Реструктурируйте действие, чтобы оно выглядело как поле ресурса. Это работает, если действие не принимает параметры. Например, действие активации может быть сопоставлено с булевым activated полем и обновляться через PATCH для ресурса.

  2. Относитесь к нему как к ресурсу RESTful. Например, API-интерфейс GitHub позволяет отображать gist с помощью PUT /gists/:id/star и notar с помощью DELETE /gists/:id/star .

  3. Иногда у вас действительно нет способа сопоставить действие с разумной структурой RESTful. Например, поиск нескольких ресурсов не имеет смысла для применения к конечной точке конкретного ресурса. В этом случае /search будет иметь наибольший смысл, даже если он не является ресурсом. Это нормально - просто сделайте то, что правильно с точки зрения потребителя API, и убедитесь, что оно четко задокументировано, чтобы избежать путаницы.


Общие практики

  • API документирован. Инструменты помогут вам создать вашу документацию, например Swagger или Spring REST Docs .

  • API версируется , либо через заголовки, либо через URL-адрес:

https://example.com/api/v1.2/blogs/123/articles
                        ^^^^
https://example.com/api/v1.2/blogs/123/articles
                             ^^^^^     ^^^^^^^^
  • В URL-адресах используется кебаб-код (слова разделены нижней частью и разделены тире):
https://example.com/api/v1.2/quotation-requests
                             ^^^^^^^^^^^^^^^^^^
{
  ...,
  _links: {
    ...,
    self: { href: "https://example.com/api/v1.2/blogs/123/articles/789" }
    ^^^^
  }
}
  • Соотношения HATEOAS используют lowerCamelCase (слова имеют нижнее значение, затем заглавные буквы за исключением первого, а пробелы опущены), чтобы позволить клиентам JavaScript использовать точечную нотацию при соблюдении соглашений об именах JavaScript при доступе к ссылкам:
{
  ...,
  _links: {
    ...,
    firstPage: { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" }
    ^^^^^^^^^
  }
}

Управление блогов через HTTP-API RESTful

Следующие примеры используют HAL для выражения HATEOAS и используют:

  • CURIE (Compact URI): используется для предоставления ссылок на документацию API
  • Шаблоны URI : URI, который включает параметры, которые должны быть заменены до разрешения URI

Получить блог 123

Запрос

GET https://example.com/api/v1.2/blogs/123
headers:
  Accept: application/hal+json

отклик

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 123,
    "title": "The blog title",
    "description": "The blog description",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123" },
      "doc:articles": { "href": "https://example.com/api/v1.2/blogs/123/articles{?pageIndex,pageSize}", "templated": true }
    }
  }

Создать новую статью в блоге 123

Запрос

POST https://example.com/api/v1.2/blogs/123/articles
headers:
  Content-Type: application/json
  Accept: application/hal+json
  X-Access-Token: XYZ
body:
  {
    "title": "The title 2",
    "content": "The content 2"
  }

отклик

status: 201 (CREATED)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 789,
    "title": "The title 2",
    "content": "The content 2",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
      "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
    }
  }

Получите статью 789 блога 123

Запрос

GET https://example.com/api/v1.2/blogs/123/articles/789
headers:
  Accept: application/hal+json

отклик

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 789,
    "title": "The title 2",
    "content": "The content 2",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
      "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
    }
  }

Получите 4-ю страницу из 25 статей блога 123

Запрос

GET https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25
headers:
  Accept: application/hal+json

отклик

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "pageIndex": 4,
    "pageSize": 25,
    "totalPages": 26,
    "totalArticles": 648,
    "_link": {
      "firstPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" },
      "previousPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=3&pageSize=25" },
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25" },
      "nextPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=5&pageSize=25" },
      "lastPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=26&pageSize=25" }
    },
    "_embedded": [
      {
        ...
      }, {
        "id": 456,
        "title": "The title 1",
        "content": "The content 1",
        "_links": {
          "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
          "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/456" },
          "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
          "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/456/comments{?pageIndex,pageSize}", "templated": true }
        }
      }, {
        "id": 789,
        "title": "The title 2",
        "content": "The content 2",
        "_links": {
          "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
          "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
          "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
          "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
        }
      }, {
        ...
      }
    ]
  }

Обновить статью 789 блога 123

Запрос

PUT https://example.com/api/v1.2/blogs/123/articles/789
headers:
  Content-Type: application/json
  Accept: application/hal+json
  X-Access-Token: XYZ
body:
  {
    "id": 789,
    "title": "The title 2 updated",
    "content": "The content 2 updated"
  }

отклик

status: 200 (OK)
headers:
  Content-Type: application/hal+json
body:
  {
    "id": 789,
    "title": "The title 2 updated",
    "content": "The content 2 updated",
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
      "doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
    }
  }

Заметки

  • Идентификатором, который используется для идентификации ресурса для обновления, является тот, который указан в URL-адресе : тот, который находится в теле (если есть), должен быть молча игнорирован.
  • Поскольку запрос PUT обновляет весь ресурс, если content не был отправлен, он должен быть удален из сохраненного ресурса.

Удалить статью 789 блога 123

Запрос

DELETE https://example.com/api/v1.2/blogs/123/articles/789
headers:
  Accept: application/hal+json
  X-Access-Token: XYZ

отклик

status: 204 (NO CONTENT)
headers:
  Content-Type: application/hal+json
body:
  {
    "_links": {
      "curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
      "doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" }
    }
  }

Нарушение REST

<stock>
    <add>
        <item>
            <name>Milk</name>
            <quantity>2</quantity>
        </item>
    </add>
</stock>

Помещение этого тела к ресурсу, подобному /stocks/123 нарушает идею REST. Хотя это тело put и содержит всю необходимую информацию, оно также сопровождается вызовом метода для add где-то, когда тело обрабатывается. Следуя за REST, вы отправите item в /stocks/123/items/ .



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow