Степень детализации отношения ссылки против точности в пользовательском типе носителя? - PullRequest
5 голосов
/ 27 февраля 2012

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

Чтобы продемонстрировать проблему, допустим, что у меня есть ресурс, на котором я могу выполнять стандартные методы чтения, изменения, удаления и что для реализации этих методов я использую HTTP-идиомы GET, PUT и DELETE соответственно.

Я мог бы разумно (повторно) использовать отношение ссылки "edit" (из реестра ссылок IANA ), как определено в RFC5023 , в котором говорится:

"... Значение" edit "указывает, что значение атрибута href является IRI редактируемой записи участника. При появлении в atom: entry, href IRI может использоваться для извлечения, обновления и удаления Ресурс, представленный этой записью .... "

Таким образом, пользовательский агент может понять, что ссылка с отношением «редактировать» позволит ресурсам быть GET, PUT и DELETEd.

Однако в этом и заключается проблема: если состояние ресурса редактируется так, что ресурс теперь поддерживает только операции GET и DELETE, отношение «редактировать» больше не является точным.

Чтобы сохранить точность, мне нужно либо i) ВАРИАНТ A: указать другое (составное) отношение ссылок, поддерживающее только GET & DELETE, либо ii) OPTION B: указать отдельные ссылки для каждой возможной передачи состояния и использовать соответствующие те, чтобы указать разрешенные государственные переводы. Последний подход предлагает точность, но кажется слишком многословным.

В качестве альтернативы (ОПЦИЯ C) я мог бы оставить отношение «редактировать» на месте и принять отсутствие точности, то есть ссылка передавала бы семантику GET, PUT, DELETE, но пользовательский агент, пытающийся PUT, встретился бы с Ошибка HTTP «405 - метод не разрешен». Тем не менее, я не доволен этим подходом, так как он подразумевает для клиента переход состояния, который не поддерживается.

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

Ответы [ 3 ]

2 голосов
/ 16 мая 2012

После серьезного расследования я пришел к выводу, что пытаюсь решить не ту проблему. Вместо того, чтобы интересоваться гранулярностью HTTP-глагола в определении Связи ссылок, более изощренный вопрос: «Должны ли идиомы (глаголы) HTTP объединяться в Связи ссылок?».

Я использовал AtomPub в качестве справочного материала о том, как сделать отношения ссылок (для REST), и оказалось, что это было ошибкой. В почтовом архиве AtomPub Рой Филдинг сообщает, что (в терминах REST) ​​подход к «редактированию» неверен, и приходит к выводу, что он не нужен. Аргумент предполагает, что существуют другие (HTTP) механизмы для передачи таких свойств и, следовательно, им нет места в атрибуте rel.

Другие механизмы не указаны явно в почтовом архиве, но я подозреваю, что они включают в себя следующие параметры:

  1. Пусть пользовательский агент попытается проверить ответ (2xx или 4xx) или
  2. Используйте OPTIONS, чтобы запросить ресурс о разрешенных операциях, или
  3. Включить заголовок «Разрешить» в успешных запросах GET для передачи разрешенные операции с ресурсами для агента пользователя.

Интересно, что Рой считает заголовок «Разрешить» «формой гипертекста».

Итак, ответ на мой вопрос:

" Не путать операции HTTP в значении 'rel' "

и

" Использование (предоставляемых) механизмов HTTP для определения разрешенных операций с ресурсами "

Редактировать: я должен добавить, что есть некоторые специальные применения POST в качестве приемника данных, где эти правила должны немного сгибаться, но тогда это особый случай.

1 голос
/ 28 февраля 2012

Спецификация WRML использует подход, при котором каждый объект "ссылка" может иметь свойство rel.

GET /dogs/1
{
    "links" : {
        "self" : {
            "href" : "http://api.example.com/dogs/1
            "rel" : "http://api.example.com/relations/self"
        }
    }
}

И клиент может затем следовать URL-адресу Rel

GET /relations/self
{
   "name" : "self"
   "description" : " A reference back to the same object you are currently interacting with" 
   "method" : "GET"
}

Спецификация рекомендует, чтобы для каждого rel был указан ровно 1 метод. Это дает возможность четко указывать своим клиентам, что они должны делать, и ограничивает объем необходимых внешних знаний. Я лично возвращаюсь к этому вопросу, потому что думаю, что есть некоторая ценность в том, что определенные "rel" предоставляют несколько методов HTTP. Представьте ссылку для владельца собаки

GET /dogs/1
{
    "links" : {
        "self" : {
            "href" : "http://api.example.com/dogs/1
            "rel" : "http://api.example.com/relations/self"
        }
        "owner" : {
            "href" : "http://api.example.com/owner/1
            "rel" : "http://api.example.com/relations/owner"
        }
    }
}

Было бы хорошо, если бы "владелец" подразумевал GET и PUT, так как это допустимые действия. В противовес этому, вы всегда должны делать GET перед обновлением, поэтому ценность предоставления этой информации перед извлечением ресурса является неправильной.

Так что, думаю, все, что сказали, я бы проголосовал за ВАРИАНТ B.

0 голосов
/ 28 февраля 2012

Другой вариант - оставить отношение «редактировать» и позволить потребителю, который хочет знать, что он может в данный момент выполнять на ресурсе, сделать запрос с помощью HTTP-метода OPTIONS, а сервер может вернуть ответ с Разрешить заголовок , чтобы указать разрешенные методы для ресурса, учитывая его текущее состояние.

Он не дает вам доступности операции PUT без дополнительного запроса, но довольно «чист» ипозволяет использовать стандартные отношения и механизм HTTP.

...