LINUX.ORG.RU

RESTful, как правильно организовать один момент

 , , ,


0

1

Други, пишу web-сервис, Django REST API и клиент на jQuery Mobile. Ситуация простая. Есть таблица баз данных (модель), выдаваемая через rest в /orders/, для обычных пользователей она read only. Это как-бы список заказов. Пользователи должны иметь возможность смотреть заказы GET на /orders/100500/, и принимать заказы, т.е. иметь право изменять одно поле в таблице. Так вот, каким образом последнее лучше реализовать? Сделать отдельный url вида /orders/take/100500 и слать туда POST, или пытаться сделать права таким образом, чтобы на /orders/100500/ можно делать PUT/PATCH, но проверять, что меняется только одно поле, и ни какие другие?

UPD: И какой код возвращать в ситуации, если уже кто-то другой принял заказ? 403 Forbidden?

Я бы запилил POST /orders/100500/take.

zz ★★★★ ()

Почитайте уже REST RFC. Там все это предельно ясно описано, то что вы хотите сделать - это ниразу не рест.

Примеры:

GET /orders - возвращает коллекцию заказов, также возможно указывать через параметрамы, например фильтрацию. GET /orders/?count=10&order=desc

POST /orders/ - Создать заказ, в параметрах(хотя лучше все же для параметров использовать JSON) указываем аргументы для функции создания.

PUT /orders/100500/ - Редактируем, так же через параметры указываем аргументы функции редактирования.

DELETE /orders/100500 - думаю понятно.

grouzen ★★ ()

Сделать отдельный url вида /orders/take/100500 и слать туда POST, или пытаться сделать права таким образом, чтобы на /orders/100500/ можно делать PUT/PATCH, но проверять, что меняется только одно поле,

Однозначно второе.

И какой код возвращать в ситуации, если уже кто-то другой принял заказ? 403 Forbidden?

В принципе, можно и его. Но вообще-то «400 Bad request» считается как бы общепринятым вариантом, поскольку «403 Forbidden» резервируется для ответа на попытку доступа при отсутствии прав на это. С другой стороны, если вы уверены, что ПО-потребитель Вашего сервиса реализован грамотно, то оптимумом будет «406 Not Acceptable»

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

Ах да, коды возврата соотсветсвенно делаются через JSON, либо если возникает ошибка, то они соотстветсвенно мапятся на http статусы, например: 403 - ошибка доступа, 404 - элемент коллекции не найден, или неверный урл и тд.

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

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

winlook38 ★★ ()

принимать заказы, т.е. иметь право изменять одно поле в таблице

Так всё таки, что делает пользователь - принимает заказ или изменяет поле? Если есть действие «принять заказ», то оно должно быть отражено в api. Например, это может выглядеть, как подача заявки на приём заказа:

POST /orders/100500
Content-Type: application/vnd.morfair.take-order-application+json

Коды возврата в такую схему тоже вписываются: сервер принял заявку - 202 Accepted; кто-то другой уже получил заказ - 409 Conflict.

А для изменения документа используется PUT, да.

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

Пользователь принимает заказ, а фактически изменяется поле ForeignKey (One-to-One) в поле этого заказа.

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

Пользователь принимает заказ, а фактически изменяется поле ForeignKey (One-to-One) в поле этого заказа.

В этом случае Вам стоит сделать API для модели, связанной (One-to-One) с заказом, и дать возможность добавлять документ методом POST именно в эту модель.

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

Заказ является документом лишь в бекенде (1С), на сервере приложений это просто ForeignKey в таблице Order на пользователя. Соответственно, если поле «исполнитель» таблицы заказов пустое - заказ свободен для выбора исполнителями.

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

Насколько я понял, у Вас есть документ заказа с которым связан один и только один документ назначения специалиста на заказ.

Если исходить их этой концепции, то у Вас должно быть две коллекции: коллекция документов-заказа, доступная только по чтению (GET), и коллекция документов назначения специалиста на заказ, доступная только для добавления (POST). Как-то так, наверное.

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

в документе заказа хранится айдишник специалиста, принявшего этот заказ. если это поле пустое, значит нико заказ еще не принял.

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

отдельной коллекции документов назначения специалиста на заказ нету

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

Пользователь принимает заказ, а фактически изменяется поле ForeignKey (One-to-One) в поле этого заказа.

А на самом деле там вообще электроны по проводам летают. То, что там изменяется внешний ключ - деталь реализации. Апи должен отражать суть действий. Для пользователя апи название функции «изменить внешний ключ» не несёт никакого смысла, а только говорит о том, что, видимо, используется rdbms (то бишь, никакого веб-скейла). Используйте термины предметной области: «подать заявку на получение заказа» или «назначить специалиста на заказ».

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

Я, видимо, логически не понимаю, что должна нести коллекция документов назначения специалистов заказам...

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

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

Конкретно в Вашем случае, сопутствующий документ несет в себе ссылку на документ заказа и реквизиты специалиста. Как только он появляется у вас, заказ меняет статус с, допустим, «новый» на «назначен специалист»

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

Кстати, документ заказа с его статусами и, возможно, решением (solution) должен быть спроектирован как конечный автомат.

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