я должен поместить соединительные слова в моем успокоительном API или нет? - PullRequest
3 голосов
/ 19 марта 2011

Допустим, у меня есть контроллер, который принимает три параметра:

class Dog {
    function tell (dogId, commandId, rewardId) {
         // blah
    }
}

Мой URL для доступа, который может быть:

 mysite.com/dog/tell/1/2/3

В этом случае вы должны помнить, что параметры отображаются в dogId, commandId & rewardId в этом порядке. Другой путь может быть что-то вроде:

mysite.com/dog/tell/1/command/2/reward/3

или для еще большей ясности (но, вероятно, больше поиграть с вашими фреймворками):

mysite.com/tell/dog/1/command/2/reward/3

Что лучше? Что чаще встречается? На первый взгляд кажется, что чем чище, тем лучше. Однако вы все еще должны помнить, каков порядок параметров, и теперь вы должны также запомнить ключевые слова. («Это была« собака / команда / награда »или« команда / собака / награда »или« собака / к / за »или ...?»)

Мысли? Рекомендации? :)

Ответы [ 4 ]

4 голосов
/ 20 марта 2011

Вы, похоже, не создаете RESTful API здесь.API REST используют URI для обозначения ресурсов, а не операций (tell выглядит для меня как операция).Операции над ресурсами определяются интерфейсом, который является общим для всех ресурсов.Я предполагаю, что вы разрабатываете REST API с использованием HTTP, поэтому ваш общий интерфейс определяется HTTP-глаголами GET, POST, PUT, DELETE и т. Д.

Итак, вместо того, чтобы определять наш сервис с точки зрения операцииtell, давайте начнем с размышления о ресурсе: собака.Как клиент, давайте предположим, что я ищу собаку Ровера.Моим первым взаимодействием с вашим сервисом может быть запрос, подобный следующему:

GET mysite.com/dogs?q=Rover

В рамках ответа на этот запрос предположим, что мне дан URL-адрес ресурса, представляющего собаку Rover: mysite.com/dogs/3759

Теперь давайте выясним состояние собаки Ровера:

GET mysite.com/dogs/3739

В ответ я вижу, что собака Ровера жива, не спит и стоит (т.е. ответ говорит мне: состояние Ровера пса).Ответ также включает в себя формы, которые я могу использовать, чтобы вызвать переход в состояние этого ресурса (т.е. ответ говорит мне, как сделать состояние изменения Rover).

Теперь, следующий шаг - сказать Rover сделатьчто-то.Мы хотим, чтобы состояние Ровера переходило из положения стоя в положение сидя (предположим, что мы не можем просто обновить состояние Роверса из положения стоя в положении сидя, мы можем только выдать команду, которой Ровер может следовать - как настоящая собака!).Давайте отправим команду sit в Rover:

POST mysite.com/dogs/3739
<command name="sit"/>

Мы можем думать о команде как о собственном ресурсе - у него есть «имя» (сидеть), эмитент (я), собака(Rover), и за ним также можно следить или не следовать (в зависимости от настроения собаки).Теперь в своем ответе на этот POST я получаю следующую информацию

Status  : 201 (Created)
Location: mysite.com/dogs/3739/commands/1299

Статус говорит мне, что эти данные были получены Rover, и это вызвало создание нового ресурса (наша команда).Если мы хотим получить состояние этой команды, мы можем увидеть это, сделав запрос к URL-адресу, указанному в заголовке Location.Давайте сделаем это и узнаем о нашей недавно созданной команде:

GET mysite.com/dogs/3739/commands/1299

Теперь в ответе будет указано состояние этой команды.Давайте предположим, что нам повезло: команда была выполнена (возвращаемое представление для этого ресурса включает некоторую информацию, такую ​​как followed=true).Ответ также включает в себя ссылку на ресурс, который представляет Rover (собака, которой была дана команда).

Наконец, когда мы запрашиваем состояние ресурса, представляющего Rover:

GET mysite.com/dogs/3739

Из ответа мы видим, что произошел переход состояния, и теперь нам говорят, что Rover 'сидя.Ответ может также включать ссылку на список команд, которые Rover выпускал на сегодняшний день, в виде ссылки на этот URI:

mysite.com/dogs/3739/commands/

Это IMO намного ближе к модели RESTful.Домен, который вы выбрали здесь, может затруднить объяснение и понимание, я думаю.Ресурс «команда» сбивает с толку и звучит очень RPC, но слово «команда» действительно используется только потому, что мы говорим о домашних животных.На самом деле «команда» - это просто сообщение, которое вы посылаете собаке.Когда мы заменяем слово «команда» словом «сообщение», становится легче увидеть, что сообщение - это ресурс, который, безусловно, имеет состояние.

Короче говоря (tl; dr):

  • присваивать URI ресурсам, а не операциям
  • создавать / обновлять ресурсы (вызывать переходы состояний), отправляя данные (не «вызывая операции»)
  • , если возможно, с каждым ответомсвоему клиенту помогите им выполнить следующий переход состояния с помощью ссылок и форм (они позволяют клиенту обновлять свое собственное состояние и обновлять состояние приложения).

Для более подробного чтения есть отличный примеро взаимодействии RESTful, описанном здесь:

http://www.infoq.com/articles/webber-rest-workflow

Этот пример кафе усовершенствован и расширен в книге Джима Уэббера и Яна Робинсона «ОТДЫХ на практике».

Конечно, возможно, стоит перечитать Филдинг (я думаю, наиболее актуальным является раздел 5.2):

http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

Трудно объяснить в одном посте (извините за длину!) но я надеюсь, что это поможет.

1 голос
/ 19 марта 2011

Лично я предпочел бы иметь URL-адрес, подобный mysite.com/dog/1/tell, и передать ему команду = 2 и вознаграждение = 3 через POST. Возможно, идентификатор собаки может быть в данных тоже. Несколько причин:

  1. Действия, которые имеют последствия, не должны выполняться через GET, но наличие всего запроса в URL делает GET очень заманчивым.
  2. REST говорит только о том, что запрос должен содержать все необходимое для выполнения действия, а не URL-адрес. Учитывая # 1, я бы даже сказал, что вставлять все в gettable URL - плохая идея.
  3. делает его намного более универсальным; HTML-форма, размещаемая по URL, будет достаточна для ее проверки.
  4. Как уже упоминалось, URL-адреса предназначены для формирования иерархического пространства имен. Вы нарушаете это, когда вы помещаете свои параметры в URL, так как (1) нет четких отношений родитель / потомок между, скажем, «командой» и «вознаграждением», и (2) если ни один из параметров не является необязательным, это делает для много недействительных URL. Присвоение имен параметрам делает это еще хуже, так как теперь один и тот же «ресурс» имеет 6 разных и одинаково функционирующих URL-адресов ... и это если ваша инфраструктура действительно поддерживает это.
0 голосов
/ 19 марта 2011

mysite.com/tell/dog/1/command/2/reward/3

очень похоже на

mysite.com/tell?dog=1&command=2&reward=3.

Во втором случае порядок определенно не важен.Скорее всего, в первом случае это тоже не важно.На вашем месте я бы принял любую комбинацию, потому что она явно не иерархическая, как ожидается от URL.Более того, вы не можете ожидать, что mysite.com/tell/dog/1 сделает что-то полезное.

Поскольку идентификатор собаки, идентификатор команды и идентификатор вознаграждения имеют смысл только вместе, я бы констатировал этот факт, устанавливая порядок тоже:

mysite.com/tell/dog-a-command-rewarding-by/1/2/3

или даже

mysite.com/tell/dog-a-command-rewarding-by/1-2-3

, потому что вы не можете ожидать, что mysite.com/tell/dog-a-command-rewarding-by/1 тоже сделает что-то полезное.

0 голосов
/ 19 марта 2011

Для веб-сайта я бы сказал, что наличие соединительных слов полезно, для API, я бы сказал, не очень, хорошая документация - это все, что требуется для API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...