TGTGInsightаналитика telegramLIVE / telegram public index
← Системный сдвиг
Системный сдвиг avatar

TGINSIGHT POST

Post #530

@systemswing

Системный сдвиг

Просмотры4,059Количество просмотров
Опубликован3 дек.03.12.2024, 11:52
Содержимое поста

Содержимое

На тренинге по интеграциям возник вопрос: что куда класть в http-запросе (в REST API). Решил разложить по полочкам (pun intended). Полочек в http четыре штуки: ➡️путь — path или route, эндпоинт, он же на жаргоне яндексоидов "ручка" (то, что после адреса сервера, за символом '/' — иерархия типов ресурсов и их идентификаторов. По аналогии с путем к файлу на диске, в пути говорят о вложенности — как будто каждый следующий уровень в цепочке '/' вложен в предыдущий. То есть, /orders/123456 — это заказ с id=123456, а /orders/123456/items — это перечень товаров в этом заказе, товары "вложены" в заказ) ➡️параметры запроса, или query (то, что в конце URL, за символом '?' — перечисление параметров в формате имя=значение, разделенных &.) Метод http, путь, параметры и версия протокола вместе называется называется строкой запроса или стартовой строкой. Строки запроса сохраняются в логах сервера. ➡️заголовки запроса — http headers (передаются после строки запроса в виде пар "имя":"значение"). Обычно не сохраняются в логах, но иногда могут (можно настроить частичное сохранение — например, значение cookie или токенов точно не нужно сохранять, т.к. их можно использовать для выдачи себя за другого пользователя). ➡️тело запроса — http body (тут понятно, это сами содержательные данные, которые мы передаем). Есть из чего выбрать! Понятно, что идентификатор запрашиваемого ресурса мы обычно размещаем в пути, а содержимое помещаем в теле запроса (если это POST/PUT/PATCH). А если мы хотим указать связь нашего ресурса с другим? Например, связь заказов с клиентом? Тут уже могут быть два варианта: nested resources (вложенные ресурсы: /clients/689697/orders) или flat (плоские: /orders?client=689697, в API только пути с названиями ресурсов). А если мы хотим указать версию API, у нас ещё больше вариантов: путь (/api/v1/orders), параметры (/api/orders?version=1) и заголовки (через кастомный заголовок: X-API-Version: 1, или через стандартный заголовок Accept: application/json; version=1 ). Я видел даже парочку случаев, когда версия передавалась в теле(!), даже для GET (хотя вообще сервер должен игнорировать тело GET-запроса). Или, например, параметры пагинации. Тут у нас опять варианты: параметры, заголовок или тело. В пути не видел, но не исключаю — фантазия у людей безгранична. Вопросы эти очень дискуссионные, я для себя выработал такие правила: Путь — это указатель на коллекцию ресурсов или конкретный экземпляр. Лучше не тянуть туда ни версионность, ни фильтры, ни метаданные. Идентификатор в пути может быть только один (то есть, если мы описываем вложенные ресурсы, там может быть идентификатор на конце, или вторым от конца. Таким образом, вложенность будет только двухуровневая, и не будет диких URL типа /cities/77/pickpoints/35/clients/689697/orders/123456/items) Параметры запроса — это ограничения на выдаваемую коллекцию ресурсов или набор полей одного ресурса. Поэтому тут будет простой поиск, фильтрация, набор полей в выдаче, пагинация, сортировка. То есть, это метаданные, относящиеся к ресурсу. Если мы хотим получить заказы клиента, доставленные в пункт выдачи с id=35, это будет выражено так: clients/689697/orders?city=77&pickpoint=35 (мы ограничиваем спискок заказов). Заголовки — это метаданные запроса (а не ресурса). Это всё, что касается форматов выдачи (я видел API, в которых формат был зашит в путь: /api/xml/orders и /api/json/orders — не делайте так!), версии API и версии ресурса, кэша, параметров соединения, id запроса и т.п. Дискуссионный вопрос про пагинацию: её можно поместить и в заголовки тоже, как и ответную информацию (текущая страница, общее число страниц, число записей всего, следующая страница, предыдущая страница). Часто метаинформацию про пагинацию помещают в тело ответа, но, как по мне, это перегружает структуру ответа и может сделать её разнотипной для разных ответов — будьте с этим осторожнее.