LINUX.ORG.RU

Какой способ построения RESTapi предпочитаете?

 , ,


0

2

Способ №1:

/api/users/ # method: get (get users list)
/api/users/add/ # method: post (add user)
/api/users/info/<id>/ # method: get (get user info)
/api/users/delete/<id>/ # method: post (delete user)
/api/users/edit/<id>/ # method: post (edit user)

Способ №2:

/api/users/ # method: get (get users list)
/api/users/ # method: post (add user)
/api/users/<id>/ # method: get (get user info)
/api/users/<id>/ # method: put (edit user)
/api/users/<id>/ # method: delete (delete user)

★★★★★
Ответ на: комментарий от znenyegvkby

Any information that can be named can be a resource

Да ты чтец между строк. Каким образом ключевая фраза противоречит произвольному однозначному меппингу, не завязанному на http методы? И какое свойство REST системы нарушается, если вместо DELETE /user/1 будет POST /user/1/delete ? Ответь просто, можно цитатой из бумаги.

A1
()
Ответ на: комментарий от abc

Вот тут все отлично описано про REST API.

Автор, мягко говоря, дает там вредные советы. Использовать Accept для версии API и при этом промолчать о кешировании, хотя он вообще молчит о кешировании и лепит гордый шильдик REST.

A1
()
Ответ на: комментарий от A1

Вот зачем ты сам на свой вопрос отвечаешь в сообщении, и все равно просишь меня каких-то цитат. Тут и бумаги никакой не нужно, Карл! Отвечу тебе цитатой из зеленого слоника, если ты не против :D

Им родина дала возможность с передачей запроса указывать состояние (DELETE /user/1), не хотим, хотим жрать говно (POST /user/1/delete). И это программисты?

Ну дальше ты и сам знаешь... :)

Да ты чтец между строк. Каким образом ключевая фраза противоречит произвольному однозначному меппингу

Ты хоть видел на что я отвечал? И просто в догонку. Да, «произвольному меппингу» ничего не может противоречить. Назвать ресурс «/zratgovno» вместо «author/18» чтобы запутать клиента - это ты завсегда можешь. На-крайняк отмахнешься от всех доками. «Онотоле одобряэ» :)

Ответь просто

Хорошо, отвечу просто. Нарушится свойство не REST системы, а используемого тобой протокола. Если спецификация говорит тебе, используй DELETE тогда-то и тогда-то, используй его, а не городи огороды посредством URL. Не нравится - используй другой протокол, вот беды то :) И только не нужно мне сейчас говорить о «твоем любимом браузере», который ничего не поддерживает кроме 2-3 методов. Это уж точно не проблема спецификации.

znenyegvkby
()
Ответ на: комментарий от znenyegvkby

произвольному однозначному меппингу

Мельком прочитал, извиняюсь, глаза уже липнут, спать надо идти :) Все равно это ничего не меняет. Страна дала тебе DELETE, используй DELETE, не нужно тут из себя high-level архитектора строить. Иначе, по твоей аналогии, методы в HTTP протоколе вообще фиг знает зачем описали.

znenyegvkby
()

№2 конечно, №1 это вообще не REST.

Legioner ★★★★★
()
Ответ на: комментарий от redixin

POST создание а PUT модификация? Почему не наоборот?

PUT это идемпотентный глагол. Но вообще говоря лучше, когда клиент генерирует ID и создаёт с помощью PUT.

Legioner ★★★★★
()
Ответ на: комментарий от znenyegvkby

Даже то, что у автора users вместо user в топике, уже неверно отражает ресурс. Должно быть единственное число, конечно же. Об остальном умолчу.

Правильно писать users, во множественном числе.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Но вообще говоря лучше, когда клиент генерирует ID и создаёт с помощью PUT.

Не самая лучшая затея доверить создание ID клиенту. Если конечно этот ID не уникальный логин пользователя.

Siado ★★★★★
() автор топика
Ответ на: комментарий от Siado

Почему? Всегда есть проблема пропадания связи при действии. Если это PUT, мы можем его повторять, пока он не сработает. Если же это POST, повторять его может быть чревато, действие может выполниться два раза.

Если использовать в качестве ID случайное 128-битное число или выставить генератор ID в качестве ресурса, что плохого в генерации ID клиентом?

Legioner ★★★★★
()
Ответ на: комментарий от znenyegvkby

В первую очередь это общепринято. Это главный и по сути основной аргумент за REST. Ценности в REST немного, основная ценность в том, что это набор соглашений для клепания однотипных API. Плюс однотипности в том, что тебе не надо думать при дизайне, ты просто делаешь по устоявшимся соглашениям. А пользователям твоего API опять же не надо запоминать все твои извращения, все привычные соглашения просто работают. Чем больше ты отклоняешься от привычных соглашений, тем неудобней твоё API.

Во-вторых Если /user/ будет возвращать список пользователей, это будет выглядеть странно. А если у тебя будет два разных URL-а: /users/ и /user/123, это будет выглядеть ещё страннее. А /users/123 странно не выглядит, это вполне логичная иерархия.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от znenyegvkby

Пока обед, приведу свои аргументы.
Лично для меня, плюрализация на данный момент используется как стандарт только лишь по нескольким причинам. Первая, и достаточно весомая из них - конечно же консистентность запросов для одного ресурса. Вторая, не менее важная - это удобство работы в коде, подразумевая под ресурсом всегда их коллекцию, программист и работает зачастую только с коллекцией. GET /resources, в коде get array/tuple/etc.resources[0], GET /resources/15/subresources, в коде get array/tuple/etc.resources[id].subresources, и т.д. и т.п.
Но есть еще немаловажный аспект: с точки зрения потребителя - API должен быть предсказуемым. Не всегда клиенты досканально изучают доки, и будем честными, не всегда название ресурса имеет для клиента предсказуемый вид множественного числа, особенно если клиент не бум-бум в english. И отсылка к докам, может быть хоть и правильным решением, но зачастую жестким. Так можно и клиента потерять.
Сингулярность так же имеет преимущества.
Это и более предсказуемое API для клиентов, которые не принимали плюрализацию как «негласный стандарт», то есть, очевидно для клиента GET /users имеет большую предсказуемость для возврата именно коллекции, а GET /user/1, соответственно, более предсказуема для тех, кто ждет объект. Точно так же как и операция GET /user просто не имеет смысла.
Еще один плюс сингулярности - целостность внутри самой системы. C классами/таблицами/etc зачастую принято работать именно сингулярно.
Подведу итог. Лично я, при проектировки REST применяю оба этих подхода. Зачастую применяется маршрутизатор, перенаправляющий однотипные запросы внутри сервиса в одну точку для обработки. Все что нужно программисту, это добавить новое правило, если ресурс имеет множественное число. Тогда клиент получает некоторое преимущество в предсказуемости. Особенно в ситуациях, когда без доков ему сложно подобрать множественность, допустим address -> adresses, city - cities, и т.д.. Многие почему-то думают что такой «гибридный» подход усложняет поддержку, но при правильном роутинге это не так.
Если у вас реальные недостатки гибридного построения идентификаторов, пожалуйста, приведите и их.

znenyegvkby
()
Ответ на: комментарий от Legioner

Извиняюсь, долго писал, не видел. Я привел свои за и против плюрализации, так и сингулярности. Описал почему выбираю зачастую гибрид. Можете, пожалуйста, пояснить ваше мнение по поводу гибридного подхода.
Ваше мнение по поводу плюрализации мне понятно. Спасибо за объяснения.

znenyegvkby
()
Ответ на: комментарий от znenyegvkby

Моё основное мнение в том, что какой-то существенной разницы между этими подходами нет. Это как обсуждать — сколько пробелов должно быть в коде — 2, 4 или 8? Да сколько угодно. Ну 8 вроде многовато, но разницы то существенной нет. Что существенно — чтобы это число пробелов было одинаковое во всём проекте. А лучше всего — во всех проектах на этом языке.

Исходя из этого лучше выбирать такой вариант, который исторически используется чаще и к которому люди больше привыкли. Потому что если нет разницы — зачем усложнять? У меня такая точка зрения на это.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Если это PUT, мы можем его повторять, пока он не сработает. Если же это POST, повторять его может быть чревато, действие может выполниться два раза.

Ну это смотря как подойти. Например я вижу это дело так, что POST - всегда добавляет новую запись, PUT всегда изменяет существующую. Если на PUT сделать возможным и добавлять (если запись не существует) и редактировать существующую - то может всплыть такой фичабаг, как хочешь добавить новую запись, но умудрился отредактировать уже существующую, т.к. айдишники совпали.

Siado ★★★★★
() автор топика
Ответ на: комментарий от znenyegvkby

Если спецификация говорит тебе, используй DELETE тогда-то и тогда-то, используй его, а не городи огороды посредством URL

Молодо-зелено. А если я скажу что с некоторых мобилок не уходит DELETE из webview? Это продакшен, детка.

A1
()
Ответ на: комментарий от A1

А если я скажу

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

И только не нужно мне сейчас говорить о «твоем любимом браузере»/«мобилке»/вставь что хочешь, который ничего не поддерживает кроме 2-3 методов. Это уж точно не проблема спецификации.

Причем тут спецификация? Делай так чтобы это работало в используемой тобой области. Не можешь сделать - используй другие протоколы для своих «мобилок из которых не уходит DELETE». Благо их хватает.

Молодо-зелено.

К чему это вообще? :) Ты можешь 30-40 лет говнокодить, и не читать документаций/спецификаций/etc на одном протоколе, и после этого ты будешь «гуру» что-ли? Если ты так и правда думаешь, тогда у меня для тебя плохие новости...

znenyegvkby
()
Ответ на: комментарий от znenyegvkby

Причем тут спецификация?

Какая спецификация? Ты о чем вообще? Я тебе привел пример, когда твой любимый DELETE не работает. И это проблемы конкретных пользователей, а ты на них срать готов. Про баги кеширования в браузерах ты тоже видимо не в курсах, и тоже готов срать, потому что плохие браузеры и прокси не уважают RFC.

и не читать документаций/спецификаций/etc

Я то как раз читаю и не упираюсь рогом в божественный DELETE.

и после этого ты будешь «гуру» что-ли

Я по крайней не отмахиваюсь от проблем реального мира.

anonymous
()
Ответ на: комментарий от anonymous

Пффф. Ты либо меня не читаешь, либо видишь то, что хочешь видеть, но никак не то что я пишу.

Не можешь сделать - используй другие протоколы/методы/etc

Я по крайней не отмахиваюсь от проблем реального мира.

Я тоже не отмахиваюсь. Я же сказал тебе уже, сколько можно повторять? Если твой браузер не поддерживает ничего, окромя GET/POST - то сделай все это через JSON-pure и не мучай REST.

Я то как раз читаю и не упираюсь рогом в божественный DELETE.

Не читаешь, ты почему то вообразил что я во что-то уперся. Это не так. Если нифига там у тебя не поддерживается, скажи мне, нафига использовать '/resource/id/DELETE/' и позорить REST, если есть возможность применить другой архитектурный стиль?

znenyegvkby
()
Ответ на: комментарий от znenyegvkby

нафига использовать '/resource/id/DELETE/' и позорить REST, если есть возможность применить другой архитектурный стиль?

Дружок, хочешь я расскажу тебе сказку? Какое свойство REST системы нарушается при использовании /resource/id/DELETE/ ? Не можешь прямо ответить — заткнись и молчи в тряпочку. Все остальные твои высеры, такое же бессмысленное кудахтанье.

anonymous
()
Ответ на: комментарий от anonymous

Ты опять все по кругу начать хочешь?
Я тебе уже скинул цитаты, осиль пятую главу в диссертации, особенное внимание удели:

Resources and Resource Identifiers
Я уже даже не знаю с чем сравнить твое непонимание. Это тоже самое, если ты сейчас насрешь на Красной Площади, а когда тебе начнут выписывать штраф, ты начнешь орать «Да я весь КОАП от корки до корки прочел, там нигде не написано что нельзя конкретно срать на Красной Площади». Вот такая вот тупая аналогия, но лучше для тебя я даже подобрать не могу :)

Ну вот прочитай внимательно пятую главу. У тебя есть схема для именования ресурсов. Вот использую схему/user/1 мы четко видим, что это ресурс пользователя с идентификатором 1, а /user/1/delete это что за ресурс такой? Ты если хочешь передавать глагол в URL, так хотя бы выбери для этого параметры (а-ля /user/1/?method=delete, всяко не так страшно как в первом варианте), но никак уж не схему, в которой ты определяешь именование ресурса.
Да ты и о себе хоть немного подумай (если сам пишешь сервис), тебе же ни один адекватный фреймворк в этом не поможет. Представь, что у тебя есть связи ресурса в двумя другими, допустим some_res_one/some_id/som_res_two/some_id/som_res_three, и как ты будешь это парсить? Если еще учитывать что после каждого названия ресурса может идти не идентификатор, а сразу твой любимый delete, а по твоей логике там может быть еще и put и patch и иже с ними. На что ты надеешься? Будешь костыли городить из тучи case + if? И после этого ты будешь мне говорить что это я во что-то там уперся рогом? Окстись, демон :)

znenyegvkby
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.