Программисты в кулуарах любят спорить на самые разные темы, адекватность предмета спора в таких ситуациях рассматривать не принято. Одними из самых активных являются дебаты относительно лучшего языка программирования.
Желая раззадорить максимальное число посетителей конференции, одна из компаний-спонсоров решила помочь программистам-таки определиться с самым любимым языком. Для чего и была создана система голосования.
Разумно предположив, что разработчики, которые часто своей целью ставят автоматизацию рутинных задач, начнут "автоматизировать" голосование, пытаясь обеспечить победу своему любимому языку, непосредственно в правила игры был включен пункт о возможности отдавать голоса неограниченное число раз.
Начав работу ровно в ночь перед конференцией (прокрастинировав до последнего, как и любой уважающий себя специалист), у разработчиков не было времени на придумывание качественной архитектуры. Более того, т.к. срок жизни системы будет составлять менее 40 часов, то такие изыскания могут показаться излишними.
Итого был выбран подход, издалека крайне напоминающий REST, но им не являющийся. Сообщения не self-descriptive, url не представляют ресурсы, но клиент-сервер, stateless и GET-запросы можны кешировать.
Можно заметить, что нас не интересует каждый конкретный голос, нам не нужно ни их различать, ни сохранять. Поэтому мы можем позволить себе терять некоторый процент запросов. Также система ориентирована на запись, если обычно говорят, что запросов на чтение на порядок больше, чем запросов на запись, то тут записей будет минимум на порядок больше, чем чтений.
Request:
GET /languages
Response
["COBOL", "Turbo Pascal", "Perl", "Lisp"]
Request:
POST /languages/vote
{
"userId": "1337",
"language": "COBOL"
}
Да, тут круче было бы делать /languages/{:id}/vote
, но есть как есть (у языков нет id, а слать их названия в query-строке кажется не очень правильным)
Response
202 Accepted
Request:
GET /languages/top
Response
{
"Lisp": 1073741824,
"Perl": 42,
"Turbo Pascal": 13,
"COBOL": 1
}
Request:
GET /users/top
Response
{
"userId289": 100, // т.е. сделал за всё время 100 запросов
"userId121": 11
}