Обложка: Выбор Request-Response парадигмы API: REST, RPC или GraphQL?

Выбор Request-Response парадигмы API: REST, RPC или GraphQL?

API определяет интерфейс, предоставляющий данные сервиса другим приложениям. Выбор правильного формата API крайне важен. Бизнес не всегда учитывает все факторы, выбирая формат. В результате не хватает возможности для добавления новых фич, которые могут понадобиться в дальнейшем.

Чтобы сэкономить время, силы, а самое главное деньги, стоит посмотреть на best practices, которые применяются на текущий момент. Это поможет разработать API, который позволит вносить необходимые изменения в будущем. За прошедшие годы появилось несколько форматов API, рассмотрим самые популярные из них.

Request-Response APIs

Первую группу API, которую мы рассмотрим, можно выделить как Request-Response API. Основные отличия данной группы:

  • Интерфейс предоставляется через веб-сервер на основе HTTP протокола.
  • API определяет набор эндпоинтов.
  • Клиенты отправляют запросы для работы с данными(получить/удалить/изменить) на данные эндпоинты.
  • Ответ в формате JSON или XML.

Самые популярные request-response API: REST, RPC и GraphQL.

REST

Самый популярный подход на данный момент. Используется такими поставщиками API, как, например, Google, Twitter и GitHub.

Когда мы говорим про REST, мы говорим про ресурсы. Ресурс — это объект, который может быть идентифицирован, назван, адресован или обработан в сети. REST представляет данные как ресурсы и использует стандартные HTTP-методы для представления транзакций создания, чтения, обновления и удаления этих ресурсов, то есть стандартные CRUD операции. По сути, все бизнес-сущности, которыми оперирует сервис, могут быть определены как ресурсы.

Общие правила, которым следует RESTful API:

  • Ресурс является частью URL.
  • Существительные вместо глаголов, вместо /getUserInfo/123 используем /users/123.
  • Для каждого ресурса создается два URL, один для коллекции, один для экземпляра коллекции, /users и users/123.
  • HTTP-методы GET, POST, UPDATE и DELETE информируют сервер о том, какое действие нужно совершить над данным ресурсом. Различные методы, примененные к одному и тому же ресурсу, выполняют различную функциональность.
  • Стандартные коды состояния ответа HTTP возвращаются сервером, указывая на успех или неудачу. Как правило, коды в диапазоне 2XX указывают на успех, коды 3XX указывают на перемещение ресурса, а коды в диапазоне 4XX указывают на ошибку на стороне клиента (например, отсутствие обязательного параметра или слишком много запросов). Коды в диапазоне 5XX указывают на ошибки на стороне сервера.
  • Ресурс, который существует только в другом ресурсе, должен быть представлен как подресурс, а не как ресурс верхнего уровня в URL-адресе. Например issues не могут существовать отдельно от репозитория, поэтому URL создания нового issue в GitHub API выглядит таким образом — /repos/:owner/:repo/issues

Помимо типичных операций CRUD, API-интерфейсы REST могут иногда нуждаться в представлении операций, не относящихся к CRUD. В этом случае обычно используются следующие подходы:

  1. Передавать действие в теле метода. Например, GitHub использует данный подход для архивации репозитория (прим. PATCH /repos/:owner/:repo).
  2. Трактовать действие как подресурс. API GitHub использует этот шаблон для блокировки и разблокировки issue (прим. PUT /repos/:owner/:repo/issues/:number/lock).
  3. Использовать отдельный ресурс. Некоторые операции, такие как поиск, ещё сложнее вписать в парадигму REST. Типичная практика в этом случае — использовать только команду действия в URL-адресе API (прим. GET /search/code?q=:query).

Плюсы:

  • Стандартное имя метода, формат аргументов и коды состояния.
  • Использует функционал HTTP.
  • Легко поддерживать.

Минусы:

  • Большой payload.
  • Множественные HTTP-запросы.

Когда использовать:

Для API, предоставляющего CRUD-операции.

Remote Procedure Call (RPC)

Удаленный вызов процедур (RPC) — это одна из простейших парадигм API, в которой клиент вызывает исполнение блока кода на сервере. В то время как REST рассматривает всё как ресурсы, RPC рассматривает действия. Клиенты обычно передают имя метода и аргументы серверу и получают обратно JSON или XML.

Правила RPC:

  • Эндпоинты содержат имя выполняемой операции.
  • Вызовы API выполняются с помощью наиболее подходящего HTTP-глагола: GET для запросов только для чтения и POST для других.

Пример:

POST /api/conversations.archive 
HOST slack.com 
Content-Type: application/x-www-form-urlencoded 
Authorization: token OAUTH-TOKEN 

channel=C01234 

Плюсы:

  • Очень прост.
  • Легковесный payload.
  • Высокая производительность.

Минусы:

  • Труден в обнаружении.
  • Практически нет стандартизации.
  • Может быть создано слишком много эндпоинтов.

Когда использовать:

Для API, предоставляющего действия, которые сложно инкапсулировать в CRUD операциях.

GraphQL

GraphQL — это язык запросов для API, который в последнее время приобрел значительную популярность. Он был разработан внутри Facebook в 2012 году до публичного выпуска в 2015 году. GraphQL позволяет клиентам определять структуру требуемых данных. Сервер возвращает именно эту структуру

Пример запроса:

POST /graphql 
HOST api.github.com 
Content-Type: application/json 
Authorization: bearer OAUTH-TOKEN 
{ 
   user(login: "kliukovkin") { 
    id 
    name 
    company 
    createdAt 
   } 
} 

Пример ответа:

{   "data": { 
      "user": { 
         "id": "MDQ6VXNlcjY1MDI5", 
         "name": "Georgii Kliukovkin", 
         "company": "myCompany", 
         "createdAt": "2009-03-19T21:00:06Z" 
      } 
   } 
} 

В отличие от REST и RPC API, GraphQL требует только один эндпоинт URL. Также вам не нужны разные HTTP-методы для описания операции. Вместо этого вы указываете в теле JSON выполняете ли вы запрос или мутацию. GraphQL поддерживает методы GET и POST.

Плюсы:

  • Один запрос.
  • Возможность добавлять новые поля и типы в GraphQL API, не затрагивая существующие запросы.
  • Проще отказаться от использования существующих полей.
  • Выполняя анализ логов, поставщик API может выяснить, какие клиенты используют определённое поле. Вы можете скрыть устаревшие поля и удалить их, когда их не используют клиенты. С REST и RPC API сложнее определить, какие клиенты используют устаревшее поле, что затрудняет удаление.
  • Small payload.
  • GraphQL строго типизирован. Во время разработки проверка типов GraphQL помогает гарантировать, что запрос синтаксически верен и действителен.
  • GraphiQL — встроенная в браузер IDE для изучения GraphQL. Данный инструмент позволяет пользователям писать, проверять и тестировать запросы GraphQL в браузере.

Минусы:

  • Серверу требуется дополнительная обработка для анализа сложных запросов и проверки параметров.
  • Оптимизация производительности запросов GraphQL тоже может быть сложной задачей.
  • Внутри компании легко предсказать варианты использования и отладить узкие места в производительности, но при работе с внешними разработчиками эти варианты использования становятся трудными для понимания и оптимизации.

Когда использовать:

Когда вам нужна гибкость запросов и поддержка консистентности. Хорошо подходит для внутреннего использования компании и плохо для персонального блога из-за своей сложности.
Когда дело доходит до выбора парадигмы API, не существует универсального решения. Каждая из парадигм API хорошо подходит для определённых вариантов использования. Важно понимать, какое решение лучше всего подойдет вашим клиентам, поможет вам достичь бизнес-целей с учетом ограничений, с которыми вы работаете.