Подход REST к GET на ресурсе с помощью суррогатного идентификатора или бизнес-идентификатора - PullRequest
7 голосов
/ 07 января 2012

У нас есть некоторые объекты, которые имеют уникальный бизнес-идентификатор (например, «my-unique-name»), а также имеют внутренний UUID (например, aa54-342-dffdf-55445-effab). Что является хорошим способом предоставить REST URI, который может возвращать ресурс с использованием любого метода.

Подход 1 - есть два URL ресурса (безобразно !!!):

* / Уникальное имя моего 1005 * / Foo-на-идентификатор

/ Foo-на-UUID / aa54-342-dffdf-55445-effab

Подход 2 - всегда использовать параметр запроса (даже если он возвращает один элемент ... кажется un-rest-lke)

/ Foo идентификатор = уникальное имя моего?

/ Foo? UUID = aa54-342-dffdf-55445-effab

Подход 3 - заставьте веб-сервис выяснить, является ли {id} UUID или нет (это может привести к ошибкам, но, по всей вероятности, будет работать нормально ...

Подход 4 - использовать UUID, разрешить использование бизнес-идентификатора в качестве параметра запроса (не знаю, будет ли это работать)

/ Foo идентификатор = уникальное имя моего?

/ Foo / aa54-342-dffdf-55445-effab

Любые мысли приветствуются.

Ответы [ 6 ]

6 голосов
/ 07 января 2012

Я бы использовал что-то похожее на вариант 4. Используйте UUID в сегменте пути в качестве URL-адреса одного ресурса. Используйте альтернативный URL в качестве поискового URL

например.

GET /foo?name=my-unique-name

303 See Other
Location: http://example.org/foo/aa54-342-dffdf-55445-effab

Вы не хотите иметь два URL, которые возвращают 200 с одним и тем же ресурсом. Это приводит к загрязнению кэша.
И теперь вы можете использовать URL-адрес GET «стиль поиска» для других типов поиска.

GET /foo?account=other-unique-value

303 See Other
Location: http://example.org/foo/aa54-342-dffdf-55445-effab

или вы можете даже искать неуникальные вещи.

GET /foo?country=a-non-unique-value

200 OK
Content-Type: application/vnd.hal+xml

<resource href="http://example.org/foo?country=a-non-unique-value">
   <resource rel="urn:acme:foo" href="http://example.org/foo/aa54-342-dffdf-55445-effab"/>
   <resource rel="urn:acme:foo" href="http://example.org/foo/ba54-299-weras-55445-effab"/>
   <resource rel="urn:acme:foo" href="http://example.org/foo/ca54-743-werre-23434-effab"/>
<resource>
5 голосов
/ 07 января 2012

Выберите одно как каноническое, а 307 перенаправьте другое на него. Если вы этого не сделаете, то рискуете, что два URI будут возвращать разные данные, потому что они были кэшированы в разное время или в разные периоды жизни. Перенаправляя с одного на другой, вы разрешаете запросам PUT, POST или DELETE аннулировать кэш одного канонического URI. Используйте 307 вместо 302, чтобы «исторические» клиенты не меняли POST на GET. Я бы порекомендовал подход 1, в котором UUID перенаправлен на бизнес-идентификатор только потому, что он красивее.

3 голосов
/ 07 января 2012

REST - это еще не все хорошие URL. Однако первый подход, на мой взгляд, не совсем REST из-за двух «ресурсов», как вы указали.

Второй подход - REST, но если вы не хотите иметь URL-адрес в стиле QS, вы можете сделать что-то вроде этого:

/foo/id-my-unique-name
/foo/uuid-aa54-342-dffdf-55445-effab

Затем вы можете разделить его с помощью регулярных выражений.

Насколько мне известно, мне нравится последний из-за красивого URL.

1 голос
/ 07 января 2012

В настоящее время я занимаюсь разработкой приложения для Android с вызовами отдыха и использовал второй подход, причина в том, что уникальный идентификатор пути отдыха удобнее в удобочитаемом формате, таком как http://example.com/rest/news/2007/6, очевидно, представляет новости за 2007 год и месяц6.

1 голос
/ 07 января 2012

Я бы пошел со вторым подходом. Moslty, потому что, говоря семантически, вы хотите получить сущность с именем foo, «фильтруя» что-то. Это что-то явно отражается в определении ограничений на его атрибуты, а именно id или uuid.

Тем не менее, REST не относится к URL. Подход, о котором вы говорите, обычно известен как «красивые ссылки». REST - это семантически управляемые операции по представлению ресурсов, выполняемые общими действиями (методы HTTP) и именами (URL).

Вы можете прочитать что-то еще на Филдис диссертации о ОТДЫХЕ.

Более того, если вы хотите быть RESTful, у вас должны быть уникальные URL-адреса для каждой сущности. Но, как указывает сам Филдинг, никто не ОСТАЕТСЯ.

0 голосов
/ 07 января 2012

Согласно принципам REST, каждое представление должно иметь уникальный URI.

Тот, у которого есть бизнес-ключ, вероятно, ссылается на связанные объекты по бизнес-ключу., так что это представление отличается от представления с UUID, которое, вероятно, будет использовать UUID для связанных объектов.

/foo/my-unique-name -> link: /foo/parent-uniquename
/internal/foo/aa54-342-dffdf-55445-effab -> link: /internal/foo/parent-xxxyyyy
...