Что за мода пошла? REST-like HTML CRUD

Adelf

Administrator
Команда форума
Вообще все эти частичные изменения данных ресурса... имея полные метаданные... такая дичь. Инкапсуляция? Не, не слышал. Не проще ли в базу данных напрямую коннектиться и там все делать? Там каждому юзеру права тоже можно настроить более-менее. Зачем такое апи?
 

Вурдалак

Продвинутый новичок
Вообще все эти частичные изменения данных ресурса... имея полные метаданные... такая дичь. Инкапсуляция? Не, не слышал. Не проще ли в базу данных напрямую коннектиться и там все делать? Там каждому юзеру права тоже можно настроить более-менее. Зачем такое апи?
Не, ну ведь они не напрямую domain model редактируют (хотя на практике они это и делают, АХАХА), они редактируют некоторую API-абстракцию. То есть, вместо cancelOrder() они машут руками и мычат «status = cancelled», а на стороне сервере нужно по «отредактированным» свойствам понять, что имелось в виду именно cancelOrder().
 

Adelf

Administrator
Команда форума
А как в рест например решать вопрос удаления пользвателя. Но в двух вариантах - когда он сам себя удаляет или когда его удаляет админ/модератор. Ресурс один. И метод один - DELETE. Однако бизнес-действия немного разные. И эвенты сгенерируются разные(UserDeletedByAdmin, or BySelf).
Придумаем какую-нибудь псевдо-сущность как со статусом?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
дамы (и господа), предлагаю эмоционировать в письмах господину Филдингу непосредственно

мопед не мой, и сочувствовать вам я, увы, не буду, не чувствую в себе такой уверенности

чем-нибудь еще могу помочь? :)
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@Adelf, по бритве оккама, сущность одна и действие одно, пока нет причины выделять новые.
Пользователь в админке и пользователь на сайте - это разные сущности потому что они в разных DOM-контекстах. Здесь REST ни при чем.
Сделай разные API, разные сервисы. /users/ - для юзеров, /admin/users/ - для админа

Вообще, REST сложнее в реализации - в RPC можно наговнокодить что-то типа deleteUserByAdmin() в API для пользователей, прописав if ($User->isAdmin()) прямо в action контроллера, и сказать, что это by design, а REST - это жесткие правила дизайна, там причуды очень заметны.
 
Последнее редактирование:
  • Like
Реакции: WMix

Вурдалак

Продвинутый новичок
Вообще, REST сложнее в реализации - в RPC можно наговнокодить что-то типа deleteUserByAdmin() и сказать, что это by design, а REST жесткий, там это сразу нарушение.
У тебя синдром поиска глубинного смысла, как ты сам любишь говорить. В REST никто не мешает делать кастомные команды, и сам пользователь может по-разному удалиться. Навскидку, отказаться от услуг и мигрировать свои данные на другой аккаунт. Оба кейса могут привести к удалению пользователя в том или ином виде, но последствия будут разные. И ты пытаешься притянуть за уши CRUD-глаголы, чтобы твоё уютное представление о REST не менялось. «там это нарушение», «это не про-христиански» и далее по тексту в Библии. Где в твоей Библии это запрещено?
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
по сути вопроса - согласен, когда сущность одна, сделать разные действия для удаления и миграции - нормально, не вижу проблем и противоречий

POST /users/user/123/mergeRequest
with=456

там есть какие-то правила для сущностей, которые как действия, но я уже не помню
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Не знаю почему @Adelf удалил свой пост, но замечание там было по делу: достаточно странно называть «говнокодом» команды, названные согласно бизнес-требованиям и защищать в то же время неявный нейминг. «Отказаться от услуг сайта» — это явное действие и сам сервер решит что именно должно происходить в момент выполнения команды, возможно в дальнейшем это будет подразумевать блокировку, а не удаление и вместо 404 будет 403. Клиент почему-то сразу считает, что это именно удаление. С таким же успехом клиент может решить, что ему нужно вызывать DELETE после миграции, ведь он где-то слышал, что миграция подразумевает удаление. В то же время, вызывать команду «Отказаться от услуг сайта» после «Миграции» может решить только человек, явно не понимающий бизнес-логики проекта. А всё от того, что CRUD API не выражает намерений пользователей явно.
 

Adelf

Administrator
Команда форума
Мне надоело одно и тоже перемешивать. Но ради тебя верну:

Вообще, REST сложнее в реализации серверной части, чем RPC.
Оно сложнее, потому что часто идет вразрез с доменом.

в RPC можно наговнокодить что-то типа deleteUserByAdmin() в API для пользователей
в смысле на правильном языке описать бизнес-действие? С правильной авторизацией и т.д.
 

WMix

герр M:)ller
Партнер клуба
если идет команда удаления, вы ли не проверяете, "какой пользователь (аноним или админ)" вызвал, вы ли не проверяете, что этот ресурс может только определенный "админ" удалить, это ли не бизнес логика? и хотя REST-ressource всегда одинаковый, на
DELETE /user/42
ответ может быть разный 403, 404 или 200, (не говоря о краде)
 

Вурдалак

Продвинутый новичок
Начинается. Что ты хотел сказать? Что в коде должны быть проверки на права? Ну так они и в явных командах будут.
 

WMix

герр M:)ller
Партнер клуба
а какая разница между правами пользователя и статусом ресурса? и то и другое необходимо проверить, только одно это внешнее свойство а другое внутреннее
(только "редактированная" статья может быть опубликована и только публишером)
в чем особый смысл глаголов, если из контекста понятно, что надо делать?
 

Вурдалак

Продвинутый новичок
а какая разница между правами пользователя и статусом ресурса? и то и другое необходимо проверить, только одно это внешнее свойство а другое внутреннее
Я тебе абсолютно серьёзно и без тени троллинга говорю: тебе нужно несколько раз обдумать вопрос, прежде чем его задавать. Ты сейчас меня спрашиваешь в чём разница между яблоком и поленом. Допустим, я буду терпелив и скажу по каким примерно характеристикам они различаются. Но в чём суть вопроса, к чему это всё? Ты можешь задавать вопрос в контексте нашей дискуссии? Или как-то объяснить какое отношение твой вопрос имеет к нашему разговору?

Ну, права — это здорово, это контекст проверки прав, который имеет опосредованное отношение к контексту основного продукта. Разные bounded contexts, понимаешь? Допустим, центральная модель понимает, что есть некие админы, обычные пользователи, но к security-проверкам это не имеет отношения, я могу из консоли запускать команды без каких-то проверок, просто хочу посмотреть как поведёт себя модель, если пользователь якобы удалит сам себя, а потом ещё ему достанется от админа.

Я тебе попробую помочь вернуться в русло дискуссии, чтобы ты понимал в чём именно наш пойнт. Что если мы хотим предоставить админу выбор как совершить харакири — от имени администрации (объявить себя нарушителем; возможно, админ почувствовал, что его пароль могли скомпроментировать и ему нужно срочно удалить самого себя с концами) или от имени обычного пользователя (устал, но обещал вернуться: у него будет возможность себя восстановить, введя свой пароль; но админ не может воспользоваться этим вариантом, поскольку пароль-то мог быть скомпроментирован). Как ты в своём универсальном методе DELETE /users/42 отличишь эти два кейса? Возможно, ты передашь параметр, но то-то и оно, ты почувствуешь, что это принципиально разные бизнес-действия и их нужно чётко различать. CRUD тут мешает.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Оно сложнее, потому что часто идет вразрез с доменом.
в смысле на правильном языке описать бизнес-действие? С правильной авторизацией и т.д.
мне тоже жаль, что ты удалил - вопрос вполне уместный,

это другая парадигма, просто твой пример про админа несколько нерепрезентативен, а вот логика, когда "отказаться от услуг сайта" должно означать 403 вместо 404 наглядно показывает ограничение всей парадигмы REST

в REST надо добавить какую-нибудь сущность вроде запроса на отказ от услуг или соответствующий статус, заставлять пользователя делать телодвижения - идти смотреть варианты статусов, заходить на подсущность, выставлять нужное значение,
это все неслабый overhead
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
откуда представление что на
DELETE /user/42
обязательно идет $this->usermapper->delete(42);
это и $this->usermapper->update(['deleted_at'=> 'now()'], [42]); может быть.
и хотя это "ресто-крад", это и логика:
заказ может быть удален (сторнирован) только если он не исполнен и только заказчиком или удален (отказан) но только исполнителем
ресурс тотже, логика и крад операции различны, модель решает
 

Вурдалак

Продвинутый новичок
откуда представление что на
DELETE /user/42
обязательно идет $this->usermapper->delete(42);
У меня нет такого представления. Ещё раз: у тебя тупо недостаточно данных, чтобы твоя модель могла понять каким именно образом админ себя удаляет. Особенно будет плачевно, если у тебя уже если уже есть готовые приложения на iOS/Android, которые уже используют ущербную логику и они в явном виде выражать своё намерение не смогут.

У тебя есть: текущий пользователь (он же админ) и действие «удалить самого себя». И всё.
 

Вурдалак

Продвинутый новичок
а вот логика, когда "отказаться от услуг сайта" должно означать 403 вместо 404 наглядно показывает ограничение всей парадигмы REST
Это решаешь не ты. Что именно под этим подразумевается — это дело владельцев проекта, и тут твои домыслы, основанные на твоих личных предпочтениях, неуместны.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
кто решает - неважно, user agent точно так же получает выбор по списку статусов с любым названием и смыслом

тут проблема в том, что на привычный объектно-ориентированный дизайн "я художник, я так вижу" это плохо укладывается, приходится делать дизайн под чужие правила при сомнительном результате, и поиметь большой overhead на сеть
 
Сверху