Вдогонку про рестовые апишки. С первого дня, что я работаю с ними, меня бесит одна вещь, которую никто не замечает. Она состоит в следующем: данные размазаны по всему HTTP-запросу.

Часть параметров нужно взять из урла, например айдишки сущностей. Другие данные – из заголовков. Если это GET/HEAD, взять параметры query string. Если POST – читать multipart или парсить json. В итоге первые 5-10 строк кода уходят на то, чтобы выковырять данные из разных мест.

Всегда поражало: почему никто не видит проблемы? Почему не заслать все в джейсоне через POST? Ради чего размазывать поля по разным местам?

Я хочу, чтобы апишка была описана данными, например словариком с полем action и params. Все в одном месте, и дальше этот словарик разруливается по полю action. Под каждый словарик пишется схема и документашка. Что еще нужно?

У этого подхода миллион преимуществ, вот хотя бы некоторые:

  • не нужно парсить урлы и query-параметры. Парсинг урлов, вычленение айдишек с приведением к числу – это сложно;

  • не нужно клеить урлы на клиенте. Это лютейшая боль: зачем вам /api/v1/users/123/orders/456 вместо {:user_id 123 :order_id 456}?

  • сообщенька отделяется от транспорта; становится неважно, как ее передали: по HTTP или иначе.

  • следствие 1: легко добавить новый транспорт. Фронтенд захотел веб-сокеты – пожалуйста, это делается за день. Напомню, что в веб-сокете никаких урлов нет, только данные.

  • следствие 2: очереди. Тяжелые сообщения можно складывать в кафки-реббиты.

  • следствие 3: тесты и сценарии. Можно подготовить файл, где каждая строка – сообщенька. После чего сказать: выполни их по порядку. В результате система придет в нужное состояние.

  • пакетный режим: тот же JSON RPC позволяет заслать несколько сообщений за раз. Их можно обработать параллельно.

  • бывает, один обработчик должен вызвать другой. Ты же не будешь слать сам себе HTTP-запрос! Подготовил сообщеньку и скормил ее функции, которая их разруливает.

Замечу, что под сообщением я имею в виду не очереди задач, а нечто другое. Сообщение – это набор данных, которые описывают действие. Удобно, когда все это хранится рядом.

Я уж молчу о том, что в классическом REST вечно не хватает методов или они неочевидны. В одной фирме коллеги чуть не подрались, когда спорили, что использовать для изменения: PUT или PATCH. Самая жесть – это запросы, которые меняют сразу несколько сущностей. Там вся концепция ресурсов идет лесом.

Сообщения удобней для понимания. Что легче читается: POST /api/v1/orders или CreateOrder? Другой пример: PATCH /api/v1/orders/123456/cancel или CancelOrder? То-то же.

Сообщения используются не только в вебе. Например, любое обращение к Postgres – это обмен сообщеньками. У них общий контейнер: метка, длина и произвольное тело, которое парсится в зависимости от метки. Как только написал парсер сообщений, считай, клиент почти готов.

В Кассандре, Кафке то же самое: заголовок/cooбщенька, заголовок/cooбщенька.

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