Стандарт отдыха: параметры пути или параметры запроса - PullRequest
32 голосов
/ 08 июля 2010

Я создаю новый сервис REST.

Что является стандартом для передачи параметров сервисам REST.Из разных реализаций REST в Java вы можете настроить параметры как часть пути или как параметры запроса.Например,

Параметры пути http://www.rest.services.com/item/b

Параметры запроса http://www.rest.services.com/get?item=b

Кто-нибудь знает, какие преимущества / недостатки у каждого метода передачи параметров.Кажется, что передача параметров как части пути, кажется, лучше совпадает с понятием протокола REST.То есть одно местоположение означает уникальный ответ, верно?

Ответы [ 6 ]

35 голосов
/ 08 июля 2010

Пути, как правило, кэшируются, а параметры, как правило, не кэшируются.

Итак ...

GET /customers/bob

против

GET /customers?name=bob
* 1008первый, скорее всего, будет кэширован (при условии правильных заголовков и т. д.), тогда как последний, скорее всего, не будет кэширован.
24 голосов
/ 29 июня 2015

tl; др: Вы можете захотеть и то и другое.


Элемент № 42 существует:

GET /items/42
Accept: application/vnd.foo.item+json
--> 200 OK
{
    "id": 42,
    "bar": "baz"
}

GET /items?id=42
Accept: application/vnd.foo.item-list+json
--> 200 OK
[
    {
        "id": 42,
        "bar": "baz"
    }
]

Элемент № 99 не существует:

GET /items/99
Accept: application/vnd.foo.item+json
--> 404 Not Found

GET /items?id=99
Accept: application/vnd.foo.item-list+json
--> 200 OK
[
]

Пояснения и комментарии

  1. /items/{id} возвращает item, а /items?id={id} возвращает item-list.
  2. Даже если есть толькоотдельный элемент в фильтрованном item-list, список единственного элемента по-прежнему возвращается для согласованности (в отличие от самого элемента).
  3. Просто так получается, что id является уникальным свойством.Если бы мы фильтровали другие свойства, это все равно работало бы точно так же.
  4. Элементы ресурса коллекции могут быть названы только с использованием уникальных свойств (например, ключи как подресурса коллекции) по очевидным причинам.(это обычные ресурсы, а URI уникально идентифицируют ресурсы).
  5. Если элемент не найден при использовании фильтра, ответ по-прежнему OK и все еще содержит список (хотя и пустой).Тот факт, что мы запрашиваем отфильтрованный список, содержащий несуществующий элемент, не означает, что сам список не существует.

Поскольку они такие разные и независимо полезны, вы можете хотеть оба .Клиент захочет различать все случаи (например, является ли список пустым или сам список не существует, и в этом случае вы должны вернуть 404 для /items?...).

Отказ от ответственности: Этот подход ни в коем случае не является "стандартным". me имеет столько смысла, хотя я чувствовал, что хочу поделиться им.

PS: Называть коллекцию предметов "get" - это запах кода;предпочитаю "предметы" или аналогичные.

6 голосов
/ 08 июля 2010

Ваш второй пример «параметров запроса» неверен, потому что «get» включен как часть пути.GET - это тип запроса, он не должен быть частью пути.

Существует 4 основных типа запросов:

 GET
 PUT
 POST
 DELETE

Запросы GET всегда должны выполняться без какой-либо информации.в теле запроса.Кроме того, запросы GET должны быть «безопасными», что означает, что никакие значимые данные не изменяются запросом.

Помимо упомянутой выше проблемы с кэшированием, параметры в URL-пути, как правило, являются обязательными и / или ожидаемыми, поскольку они также являются частью вашей маршрутизации, тогда как параметры, передаваемые в строке запроса, являются более переменными и невлияет на какую часть вашего приложения направляется запрос.Хотя потенциально может также передавать набор параметров переменной длины через URL:

GET somedomain.com/states/Virginia,California,Mississippi/

Хорошая книга для чтения в качестве учебника по этой теме: "Restful Web Services" .Хотя я предупрежу вас, чтобы вы были готовы просмотреть некоторую избыточную информацию.

4 голосов
/ 08 июля 2010

Я думаю, это зависит.Один URL для одного ресурса.Если вы хотите получить этот ресурс немного другим способом, передайте ему строку запроса.Но для значения, которое доставит другой ресурс, поместите его в путь.

Так что в вашем примере значение переменной напрямую связано с возвращаемым ресурсом.Так что это имеет больше смысла в пути.

3 голосов
/ 08 июля 2010

Первый вариант немного чище и позволяет зарезервировать параметры запроса для таких вещей, как порядок сортировки и страницы, как в

http://www.rest.services.com/items/b?sort=ascending;page=6
1 голос
/ 06 января 2015

Это большой фундаментальный вопрос. Я недавно пришел к выводу, чтобы держаться подальше от использования параметров пути. Они приводят к неоднозначному разрешению ресурсов. URL - это, по сути, «имя метода» фрагмента кода, выполняющегося где-то на сервере. Я предпочитаю не смешивать имена переменных с именами методов. Название вашего метода, по-видимому, «покупатель» (имхо, это гнилое название метода, но REST люди любят этот шаблон). Параметр, который вы передаете этому методу, является именем клиента. Параметр запроса хорошо работает для этого, и этот ресурс и значение параметра запроса могут даже кэшироваться при желании.

Нет физического ресурса ИТ-клиента. Вероятно, нет файла на диске в папке клиента, который назван в честь клиента. Это веб-сервис, который выполняет какую-то транзакцию базы данных. «Ресурс» - это ваша услуга, а не клиент.

Эта одержимость REST и веб-глаголами напоминает мне о ранних днях объектно-ориентированного программирования, когда мы пытались втиснуть наш код в виртуальные представления физических объектов. Затем мы поняли, что объекты, как правило, являются виртуальными понятиями в системе. ОО по-прежнему полезно, когда все сделано правильно. REST также полезен, если вы понимаете, что ресурсы RESTful - это сервисы, а не объекты.

...