API: REST, gRPC, GraphQL и проблемы over/under-fetching

При проектировании API важно выбрать способ структурирования запросов и ответов. Ниже — основные подходы и типичные проблемы.

CRUD и протокол

CRUD — четыре базовые операции: Create (создать), Read (прочитать), Update (модифицировать), Delete (удалить). Их можно описать поверх разных протоколов и форматов (JSON, XML, бинарный).

REST

Используются глаголы HTTP (GET, POST, PUT, PATCH, DELETE), уникальный идентификатор ресурса и существительные (ресурсы). Действие над ресурсом задаётся глаголом. Ответы — со статус-кодами (2xx, 3xx, 4xx, 5xx).

  • Ресурсы и подресурсы: /users, /users/123, /users/123/orders.
  • Идемпотентность: GET, PUT, DELETE не меняют результат при повторе; POST создаёт новый ресурс.
  • RESTful — соблюдение этих принципов; нестандартные форматы ответов или смешение семантики делают API менее RESTful.

SOAP

Концепция устарела, много легаси. Многословный XML, большие объёмы данных. JSON вытеснил XML в большинстве новых API.

RPC (Remote Procedure Call)

Клиент вызывает метод, как локальную функцию; под капотом — сетевой вызов к другому сервису. Не нужно вручную собирать URL и разбирать ответы — кодогенерация и типизация упрощают интеграцию.

gRPC

  • Основан на HTTP/2, бинарный формат (Protocol Buffers). Меньше трафика, чем JSON, строгая типизация, кодогенерация для клиента и сервера, мультиязычность.
  • Удобен для внутренней связи микросервисов.

JSON-RPC

Тот же принцип RPC, но запросы и ответы в JSON. Проще для отладки, чем бинарный gRPC; часто используется для веб-интерфейсов и внутренних API.

Over-fetching и under-fetching

  • Over-fetching: клиенту отдаётся больше данных, чем нужно. Пример: мобильному приложению нужны только посты, а API отдаёт посты с комментариями и лайками — лишний трафик и нагрузка.
  • Under-fetching: клиенту не хватает данных в одном ответе, приходится делать несколько запросов. Пример: сначала посты, потом для каждого поста — отдельно комментарии и лайки, много round-trip’ов.

Решения: фильтрация полей в REST (query-параметры для выбора полей), версионирование API под разные клиенты; для кастомизированных запросов — GraphQL, где клиент явно запрашивает нужные поля и вложенные сущности в одном запросе.

GraphQL

Язык запросов и мутации; клиент описывает структуру ответа (какие поля и связи нужны). Удобно для кастомизации ответов под разные экраны и для подписок на события. Требует продуманной схемы и защиты от тяжёлых запросов (лимиты, глубина вложенности).

Итог по выбору

  • SOAP — не рекомендуется для новых проектов.
  • REST — стандарт для клиентского API (браузер, мобильные приложения).
  • gRPC — типичный выбор для внутренних микросервисов (высокая эффективность, типизация, кодогенерация).
  • GraphQL — когда нужна гибкая кастомизация запросов и ответов одним эндпоинтом.

REST для внешних клиентов, gRPC для внутренних сервисов, GraphQL там, где важна кастомизация ответа — распространённая комбинация в современных системах.