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 заводит баг, говорит генерация отчётов не работает, бэк возвращает ошибку и вешает его на бэк. Бакэндер его смотрит и говорит - ну у нас конечно есть проблема на бэке, что отчёт долго генерируется, но вообще-то это фронт дурак - присылает второй запрос до получения ответа. А у нас отчёты генерируются по одноразовому токену, соответственно второй запрос тут же получает ошибку. И возвращает баг на фронт.

Приходит фронтендер и говорит: сами вы дураки - я один раз запрос отправляю.

За пару недель это цикл в вялотекущем режиме повторился сколько-то раз.

Пока я не пришёл, не открыл слева логи браузера, справа логи бэка и не увидел, что фронт действительно отсылает один запрос, а на бэк их приходит два.

Мистика? Нет, если знать ещё два бита информации:

  1. В наследство нам досталась генерация отчёта (с инвалидацией токена) GET-методом;
  2. Между фронтом и бэком у нас сидит nginx.

А nginx при проксировании по дефолту повторяет идемпотентные (спека) запросы по истечению таймаута. Вот и вся магия.

Более того, GET-запросы должны быть не просто идемпотентными, а безопасными.

Отсюда выводы:

  1. Проектируйте свои HTTP API вообще и REST API в частности согласно соответствующим спецификациям и принципам;
  2. Делайте свои GET-запросы хотя бы идемпотентными;
  3. И наоборот идмемпотентные запросы не делайте POST-ами (как пример - запросы с какими-нибудь развесистыми поисковыми формами);
  4. Если не знаете, что значит идемпотентный - срочно узнайте:)