Как бы вы разработали систему голосования RESTful?

В моем продолжающемся стремлении попытаться задуматься над RESTful-ness, я пришел в другое место, где я не уверен, как действовать дальше. Я создал для себя мысль о том, где я создам простую систему голосования для ресурса, подобно тому, как SO позволяет голосовать по вопросам. Итак, скажем, мой ресурс - это изображение, и я могу получить изображение с помощью идентификатора, например:

http://www.mysite.com/images/123123

И в этом примере, который возвращает, например, представление JSON изображения, например:

{
"URL":"http://www.mysite.com/images/123123.jpg",
"Rep":"100"
}

Как мне создать способ "проголосовать" за это изображение? Я бы хотел две операции; голосование и проголосовать. Клиент не должен знать, сколько веса несет каждый из них, потому что я хотел бы получить награду за выбор голосов/понижающего голоса на уровне сервера, чтобы я мог изменить ее в любое время.

Моя первая идея состояла в том, чтобы иметь что-то вроде этого:

http://www.mysite.com/vote/images?image=123123

К этому URL-адресу можно было бы POST что-то вроде следующего:

{
"Vote":"UpVote"
}

Но я настороженно отношусь к тому, что говорит RPC в маскировке. Будет ли это плохой способ разработать это? Если да, то какие другие проекты я мог бы попробовать?

Ответы

Ответ 1

Чтобы быть спокойным, вы должны вернуть что-то вроде этого

{
"URL":"http://www.mysite.com/images/123123.jpg",
"Rep":"100"
"UpVoteLink":"http://blah, blah, blah",
"DownVoteLink":"http://blah, blah, something else blah",
}

Что касается REST, то не имеет значения, каков формат ссылок. Пока ваш клиент знает, что он должен делать POST для "UpVoteLink" или "DownVoteLink", все равно, какой формат URL-адреса ему не подходит.

Кроме того, если вы решите через две недели, что вам не нравятся URL-адреса, которые вы выбрали, вы можете изменить их, и никто не будет заботиться!

Хорошо, хорошо, если вы действительно хотите предложить дизайн url, как насчет

POST http://www.mysite.com/UpVotes?url=http://www.mysite.com/images/1234.jpg

POST http://www.mysite.com/DownVotes?url=http://www.mysite.com/images/1234.jpg

Что круто об этом дизайне, так это то, что вы можете проголосовать за изображения, которые даже не на вашем сайте!

Ответ 2

В терминах ресурсов изображение - это вещь, имеющая URI (именно это делает ее ресурсом). Кроме того, он имеет множество свойств (размер, данные EXIF ​​и т.д.).

Когда вы думаете о голосовании за изображение, задайте вопрос, являются ли голоса самим ресурсом.

Скорее всего, выполнение GET on/images/23/votes вернет сводку или список всех голосов, которые пользовательский интерфейс будет использовать для отображения рядом с изображением. Всякий раз, когда вы хотите изменить эти голоса, ресурс, который вы меняете, является голосом.

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

В вашем примере вы бы определили новый формат, используемый везде на вашем сайте. Чтобы переформулировать пример yoru, возвращается GET/images/23/votes (в xml, но вы можете переформулировать его в json):

<votes>
 <link href="/images/23" rel="subject" />
 <form action="/images/23/votes" mediatype="application/json">
   <submit name="Vote" value="Up">Vote up</submit>
   <submit name="Vote" value="Down">Vote down</submit>
 </form>
</votes>

Идея этого формата заключается в том, что у вас есть универсальный способ определить, как клиент отправляет данные на сервер и создает документ. Все предыдущие примеры, которые были показаны правильно, делают URI зависимым от сервера. Я предлагаю, чтобы то, что вы отправляете на сервер, должно быть определено в формах, отправленных сервером.

Поэтому тратите больше времени на определение того, как клиент yoru json будет понимать, как создавать объекты json для отправки на основе общего языка форм, и вы обнаружите, что как только это будет сделано, у вас очень низкая связь между cient и сервером, и у сервера есть гибкость, чтобы изменить все особенности, не нарушая ваших клиентов.

Ответ 3

API-интерфейсы REST должны представлять существительные, поэтому я считаю, что первая часть верна: одно изображение представлено одним URL-адресом (например, http://www.mysite.com/images/123123). Я не уверен, что на пути /up_vote и /down_vote is можно найти путь.

http://www.mysite.com/images/123123 - это объект, и вы хотите изменить его, а не какой-либо другой URL (если вы не делали http://www.mysite.com/votes/images/123123). Я думаю, вы должны просто POST до http://www.mysite.com/images/123123. Это делает запросы GET неотъемлемо неразрушающими, поскольку он просто извлекает изображение, сохраняет проект RESTful и сохраняет ваши URL-адреса в чистоте.

Ответ 4

Если вы работаете с Rails, я бы пошел на это GET-URL:

http://www.mysite.com/images/123123/up_vote

и

http://www.mysite.com/images/123123/down_vote

1. Определите действия "up_vote" и "down_vote" в вашем контроллере изображений и увеличьте или уменьшите значение голоса вашего объекта модели изображения.

2. Задайте следующий маршрут в config/routes.rb:

map.resources :images, :member => { :up_vote => :get, :down_vote => :get }

... и вы закончили (более или менее; -)).

Ответ 5

Мне показалось бы глупым POST простой ответ, подобный тому, который завернут в JSON

Почему бы вам не сделать что-то простое, вы могли бы сделать это в вызове AJAX, чтобы сделать его удобным.

Запрос GET, отформатированный следующим образом

http://www.mysite.com/vote.php?image=123&vote=up

или POST (этот пример с использованием jQuery)

$.post("http://www.mysite.com/vote.php", {image:"123", vote:"up"});

(Предполагая PHP, но что бы ни применимо)