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

Проверенные VDS на SSD в Европе от $4 и России: Датацентр №1 от 199руб

Тема в разделе "Вопросы по теории программирования", создана пользователем Adelf, 5 апр 2016.

  1. Adelf

    Adelf Laravel&PhpStorm Команда форума

    Сообщения:
    3.075
    Ваш город:
    Казань
    Address:
    Kazan, Russia
    Country:
    Location on Map:
    По моему, вы еще на первой странице полгода назад все обсудили. И вроде ваши мнения с тех пор не поменялись. Понимать друг друга перестали только :)
     
  2. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Ну, не совсем. @grigori верно отметил, что REST в большей степени используется не на «полную», а лишь в лучшем случае на уровне level 2, поэтому мы видим тонну говно-API с CRUD-методами, ограниченными базовыми HTTP-глаголами. HATEOAS — интересная тема, правда даже в таком случае мне бы хотелось более явного RPC API а-ля GraphQL, потому что по моему опыту делать ресурсы а-ля /user/42/banUser получается геморройнее, чем если бы я просто отправлял команду BanUser с payload на определённый endpoint. Сюда же можно отнести чейнинг методов, с более-менее классическим RPC это делается проще. Я может ничего нового и не узнаю, но это может быть полезно другим, кто до сих пор верит в то, что POST /user/42 {"ban": true} — это true REST.

    Есть ещё одна причина некоторой нелюбви к REST, но это больше опять-таки относится к недо-REST: вот эти споры на уровне «POST или PUT», «DELETE или POST» в случае неоднозначных команд. С обычными бизнес-глаголами о таком задумываться не будешь. Есть такие методы, которые могут просто что-то менять в сущности, но при стечении обстоятельств (например, expires < текущего времени) они удаляют сущность, и это вводит в ступор новичков и не только: разве POST должен удалять ресурс? Также никогда нельзя быть уверенным, что один и тот же глагол не придётся разбить на 2: сейчас мы удаляем только одним способом и пишем DELETE /users/42, а через год мы сможем насчитать их несколько + нужен некий payload (чего DELETE не поддерживает). Получается, нам по умолчанию всегда нужно писать POST /resource/action. А тогда спрашивается зачем нужен REST?

    Ещё мне не очень нравится идея использовать HTTP-глагол в качестве бизнес-глагола (как с BAN): семантически, это именно HTTP-глагол. Если я хочу «отправить посылку» (post package), то столкнусь с тем, что вообще говоря, я понимаю под этим одно, а выглядит как самый обычный POST-метод. Упомянутый DELETE тоже имеет ограничения, хотя я, возможно, использую его в каком-то контексте как бизнес-глагол и хочу payload.

    Ну и про PATCH хотелось послушать, раз уж @grigori его упомянул. Как по мне, так это тот же самый треш, что и POST/PUT/DELETE, который мешает явно выделить бизнес-действие.
     
    Последнее редактирование: 12 окт 2017 в 22:51
  3. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    Тема достаточно объемная, прошу прощения за лаги в моих ответах.

    @fixxxer, спасибо за историю, не знал ее :) Проблема с REST не в том, что идею искривили, а в том, что люди его не могут. Например, в корпорации, в которой принят хороший внутренний стандарт, разработчики предпочитают в документацию по API добавить раздел с описанием нарушений стандарта. А сделать RPC, и не морочить голову с REST - боятся.
     
  4. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    Вот хороший пример, когда REST не вписывается в картину мира человека. Хорошо, что подняли тему, я так же думал, и мне долго объясняли.

    Для начала, процитирую Фаулера по твоей ссылке.
    Не надо забивать гвозди логарифмической линейкой. REST удобен для интеграции enterprise-систем.
    Для вывода каталога пользователям REST не нужен.
    Реальный пример, где REST полезен. Мой проект. Мобильное приложение, которое использует много тысяч техников Ricoh(Toshiba, AT&T, etc), они ездят по стране и чинят принтеры, и каждый каждый человек загружает каталог запчастей. Одновременно десятки тысяч человек приходят на работу, включают приложение, и грузят каталог.
    А часть из них бегает по лесам Амазонки со связью уровня 2g.

    Нельзя просто так взять, и поменять RPC-протокол. У каждой компании своя версия аппликухи, и если методы в нее вшиты - это на много лет. А самоописывающийся REST c HATEOS - можно.

    Предпочтения клиента и разное количество выводимых данных на страницу идут лесом, когда у тебя SLA на 100 тысяч одновременных раздач большого объема, и нет такого канала, который они не забьют. Пользователю приложение выведет данные, которые лежат на устройстве в IndexedDb, а грузиться все будет теми чанками, которыми удобно каналу. Хорошая связь, wifi в офисе - большие чанки, плохая скорость - маленькие чанки.
     
    Последнее редактирование: 16 окт 2017 в 15:13
  5. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    У тебя есть состояние ресурса, которое ты можешь узнать на момент запроса.
    Между вызовами консистентность состояния между клиентом и сервером не обеспечивается.
    Я не люблю слово "идемпотентность", поэтому говорю про состояние, но мы об одном.
     
  6. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    Синдром поиска глубинного смысла в HTTP-глаголах - это забавно.
    Я смотрю на стандарт, личные предпочтения - то такое.
    Это что-то вроде вопроса на какой строке ставить скобку. Как напишешь в стандарте своей компании - так и должно быть.
    Фаулер привел пример подхода.
    Выделяем доменные сущности: врачи, слоты, статусы. Нравится или нет, в REST статус - это отдельный ресурс.
    В твоем случае, есть статус поста. POST должен менять ресурс.

    процитирую тебе корпоративный стандарт:
     
    Последнее редактирование: 16 окт 2017 в 15:51
  7. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Ты ошибаешься.
    «Правильный» REST — этот тот же RPC, просто команды/запросы оформлены в виде URI.
    «Изменения» в RPC и REST имеют одни и те же проблемы: ты можешь добавить новые команды/запросы, но старые просто так поменять не получится из-за BC.
    Приложение всё равно нужно «научить» работать с новыми командами.
    Тебе ничего не мешает в JSON RPC добавить те же rels/links, просто в качестве «реализации» ресурса будут не URI, а команды/запросы в более явном виде.
    «Самоописывающий» API просто интересен тем, что ты можешь сэкономить на документации, не более. Прямого отношения к RPC/REST это не имеет.

    У меня есть опыт поддержки API, который включал в себя динамические элементы меню в iOS/Android приложения, т.е. чтобы можно было добавлять что-то в уже зарелизенное приложение. И я могу сказать, что это был ужасный опыт, потому что нативные приложения так или иначе пытались кастомизировать под свой дизайн и под своим нужды этот API, т.е. он был очень условно обратно-совместимый. Проще уж WebView встроить.
     
  8. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    Смысл HATEOS в том, что приложение сможет обработать изменение REST API. Конечно, сущности это не поменяет, но добавить в выдачу новые сущности или переименовать можно без проблем.
    <link rel = "/linkrels/appointment/cancel" uri = "/slots/1234/appointment"/>
    в
    <link rel = "/linkrels/appointment/unset" uri = "/slots/1234/appointment"/>


    Гибкость не бесплатна, конечно.
     
  9. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Что именно ты хотел этим сказать? Меня не интересует API, который оперирует понятием ресурса, как просто пачкой свойств, которую я могу полностью «заменить» или «частично проапдейтить». Мне клиент должен сообщить что он хочет (забронировать, отменить заявку, переназначить), а не status = closed, потому что в status = closed не отражает мотивации.
     
  10. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    хорошо, я не уговариваю, не интересует - не надо
    это разные подходы, и в твоих словах есть смысл

    REST предполагает, что логика клиента отделена от логики сервера полностью.
     
  11. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Ты всего лишь пытаешься повторить то, что говорит автор REST; с практикой это никак не соотносится. Если приложение будет лишь лёгкой обёрткой над таким «вебообразном» API, то это будет абсолютно примитивное приложение, которое не может обогатиться, красиво отобразить какое-то действие и т.д. в силу того, что оно слепо; оно ничего не понимает о том, что реально происходит через API. Любая попытка его обогатить ставит крест на самой идее, что API в любой момент можно поменять. С таким же успехом можно написать одно-единственное универсальное приложение, которое будет работать для любого REST API с HATEOAS, но цена такой универсальности понятна: это будет тупой FTP-менеджер, а не богатое приложение.
     
  12. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    да, повторю: REST - это набор ограничений, выработанный с целью изоляции интегрируемых систем

    когда нужна связанность и общая логика, изоляция не подходит
     
    Последнее редактирование: 16 окт 2017 в 16:21
  13. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Окей. Чем такое приложение лучше, чем просто WebView на всё приложение?
     
  14. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    для webview нет стандарта
    для "богатого" протокола есть SOAP и JSON-RPC 2, а "бедный" - вот, REST
    иногда нужно
     
    Последнее редактирование: 16 окт 2017 в 16:18
  15. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Почему же — HTML/CSS/JavaScript. Браузеры как раз этот набор стандартов и реализуют. Приложение, которое использует WebView, будет супер-универсально.

    Ты можешь возразить — приложение может реализовать что-то кастомно. А не может, потому что API в любой момент может измениться, поэтому оно должно быть тупым и не возникать.

    С моей точки зрения, тут очевидный самообман: если API может в любой момент как угодно поменяться, то приложение должно быть слепым. Если уж оно слепо, то мы получаем просто браузер. А раз мы получаем браузер, то для этого уже есть вполне себе развитые технологии. Где конкретно ошибка в этой логической цепочке?
     
  16. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    Последнее редактирование: 16 окт 2017 в 16:36
  17. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Так ведь не ты реализуешь всю сложность браузеров; за тебя это давно это сделали. CSS можешь и не использовать.

    Ты реально уверен, что те приложения, про которые ты говоришь из своей практики, не хардкодили ни в каком виде у себя последовательности appointment -> cancel для отображения, скажем, большой красной кнопки со словом «Отменить» с переводами на стороне приложения?
     
  18. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    Я совершенно уверен, что тот код, который мы писали для работы с API, ничего не выводит. Я даже хотел вынести это в web worker, но оказалось, некоторые браузеры не могут в web worker-е писать в indexedDb.
    Данные пишутся в базу сами по себе, другой "процесс" их читает и парсит в оперативку, а вывод - это отдельная задача.

    Представь, что REST используется для синхронизации данных между базами, а не для пользователя/
     
    Последнее редактирование: 16 окт 2017 в 16:47
  19. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.974
    Ваш город:
    Russia, Moscow
    Address:
    Moscow, Russia
    Country:
    Location on Map:
    Тогда каким образом программист, использующий API для отправки данных в твою базу, должен написать код таким образом, чтобы вы в любой момент могли поменять API без нарушения BC? У вас там есть, условно, тот же appointment -> cancel, программист такой: «окей, мы тут делаем отмену и для синхронизации им отправим соответствующий запрос». Тут приходишь ты, меняешь cancel на unset, cancel пропадает, у первого программиста в логах появляются 404.
     
  20. grigori

    grigori ( ͡° ͜ʖ ͡°) Команда форума

    Сообщения:
    6.671
    Ваш город:
    Stormwind
    Address:
    Scottsdale, United States
    Country:
    Location on Map:
    это уже заход на 2й круг

    У тебя есть локальное представление ресурса - пост, в нем есть ссылка на родительский ресурс - список постов (кроме того, из него был получен адрес поста).
    Состояние ресурса может измениться, и клиент к этому готов.

    Если пост уже удален - возвращай 404, клиент может перечитать список доступных постов.
    Если ты изменил адресацию, и хочешь уведомить об этом клиентов - возвращай редирект. Ваш, КО.
     
    Последнее редактирование: 16 окт 2017 в 18:04