REST, фронт и все-все-все
June 27, 2023
Я прочитал штук пять книг по REST, включая диссертацию Филдинга и для себя пришёл к выводу, что REST без HATEOS - это не REST. А HATEOS в случае толстых клиентов не работает. Соответственно смирился с тем, что мы (90% индустрии) на самом деле делаем RPC over HTTP и успокоился.
А потом наткнулся на htmx и alpine.js, с которым сейчас потихоньку играюсь и пока что в восторге - для проектов, в которых я участвовал за всю свою карьеру этого более чем достаточно и они намного проще React-ового адка, имхо. И тут уже HATEOS вполне себе работает.
Однако, я пока не представляю как хотя бы на вэб затащить htmx+alpine в коммерческих проектах, а с нативными фронтами вообще труба. Поэтому для меня HATEOS оставался скорее академической штукой, чем практической.
Пока я не посмотрел REST next level: Crafting domain-driven web APIs by Julien Topçu @ Spring I/O 2023. И вот тут у меня что-то наконец щёлкнуло и я, кажется, понял как превратить HATEOS в решение, которое повысит скорость разработки и стабильность моих систем за счёт снижения сцепленности фронтов с бэком и снижения кол-ва бизенс-логики во фронтах (и как следствие упрощения её тестирования).
Делать далеко идущие выводы я пока не готов, но совершенно точно готов дать HATEOS второй шанс в каком-нибудь пет-проекте.
Знаю, что у меня в подписчиках много молодых разработчиков - следующая история для вас, мои дорогие:)
Недавно на Проекте Э у нас был примерно такой случай.
QA заводит баг, говорит генерация отчётов не работает, бэк возвращает ошибку и вешает его на бэк. Бакэндер его смотрит и говорит - ну у нас конечно есть проблема на бэке, что отчёт долго генерируется, но вообще-то это фронт дурак - присылает второй запрос до получения ответа. А у нас отчёты генерируются по одноразовому токену, соответственно второй запрос тут же получает ошибку. И возвращает баг на фронт.
Приходит фронтендер и говорит: сами вы дураки - я один раз запрос отправляю.
За пару недель это цикл в вялотекущем режиме повторился сколько-то раз.
Пока я не пришёл, не открыл слева логи браузера, справа логи бэка и не увидел, что фронт действительно отсылает один запрос, а на бэк их приходит два.
Мистика? Нет, если знать ещё два бита информации:
- В наследство нам досталась генерация отчёта (с инвалидацией токена) GET-методом;
- Между фронтом и бэком у нас сидит nginx.
А nginx при проксировании по дефолту повторяет идемпотентные (спека) запросы по истечению таймаута. Вот и вся магия.
Более того, GET-запросы должны быть не просто идемпотентными, а безопасными.
Отсюда выводы:
- Проектируйте свои HTTP API вообще и REST API в частности согласно соответствующим спецификациям и принципам;
- Делайте свои GET-запросы хотя бы идемпотентными;
- И наоборот идмемпотентные запросы не делайте POST-ами (как пример - запросы с какими-нибудь развесистыми поисковыми формами);
- Если не знаете, что значит идемпотентный - срочно узнайте:)