GraphQL или REST: Какой API выбрать, чтобы не прогадать?

Привет, хабровчане!

Я Дима, Backend-разработчик на Go.

Расскажу о GraphQL, сравню с REST. Разберемся в плюсах и минусах каждого подхода к проектированию API. Выбираем лучший для вашего проекта!

Распространенность и интеграция

В 2015 году Facebook представил GraphQL. С тех пор эта технология набирает популярность, но REST остается лидером. По данным Postman на 2024 год, GraphQL используют 29% разработчиков, REST — 90%.

API_architectures_GraphQL_vs_REST-1024x5

Если заранее неизвестны потребители API, лучше выбрать REST — он проще и популярнее:

  • Разработчикам, знакомым с HTTP, легко освоить REST. Он использует стандартные HTTP-методы и принципы.

  • REST API можно реализовать на любом языке, поддерживающем HTTP, без дополнительных слоев.

  • REST — проверенная технология с сильным сообществом и множеством готовых инструментов.

Получение данных

GraphQL позволяет клиентам запрашивать только нужные данные, избегая избыточного или недостаточного получения. Это повышает эффективность сетевых запросов: передаются только необходимые данные.

Рассмотрим пример. Есть сущность «Игрушка» (Toy), которую создает «Мастер» (Master), привязанный к «Пользователю» (User). У игрушки также есть «Категория» (Category) и «Теги» (Tags).

GraphQL позволяет получить все данные одним запросом:

POST http://localhost:8080/query
Content-Type: application/json

query getToy {
  toy(id: 1) {
    id
    name
    description
    price
    quantity
    createdAt
    updatedAt
    category {
      id
      name
    }
    tags {
      id
      name
    }
    master {
      id
      info
      user {
        id
        displayName
        email
        phone
      }
    }
  }
}

В случае REST API потребовалась бы серия запросов:

GET http://localhost:8080/toys/1 - Получаем игрушку по ID
GET http://localhost:8080/categories/2 - Получаем категорию игрушки по ID, который взяли из объекта игрушки
GET http://localhost:8080/tags?id=1&id=2&id=3 - Получаем теги игрушки по ID, которые взяли из объекта игрушки
GET http://localhost:8080/masters/3 - Получаем мастера игрушки по ID, который взяли из объекта игрушки
GET http://localhost:8080/users/4 - Получаем пользователя, к которому привязан мастер, по ID, который взяли из объекта мастера

В приложениях со сложными связями между доменами GraphQL упрощает получение данных: один запрос вместо пяти (в примере). Кроме того, можно исключить ненужные поля, например, createdAt и updatedAt. GraphQL возвращает только то, что нужно.

Тестирование

Интеграционное тестирование на разных языках программирования отличается, поэтому посмотрим на примере регистрации пользователя через Postman.

Запрос к GraphQL API:

5j0qr0lw1dmxhgu5gerpgxmk4r8.png

Запрос к REST API:

c8966jolimq6jt-05i9cou2d240.png

Пока разница невелика, но GraphQL уже выглядит сложнее. Основная сложность — отправка файлов. Сравним запросы на создание игрушки.

Запрос к GraphQL API:

tfmvczj4jkyg2geetbrynk4rsri.png

В поле operations нужно вставить запрос:

{
  "query": "mutation CreateToy($input: CreateToyInput!) { createToy(input: $input) }",
  "variables": {
    "input": {
      "categoryId": "123",
      "name": "Example Toy",
      "description": "This is an example toy",
      "price": 19.99,
      "quantity": 10,
      "attachments": [null] // Указываем null для файлов. Сколько файлов - столько null
    }
  }
}

Поле map связывает переменные файла с attachments в operations, чтобы файлы отправились:

{
  "0": ["variables.input.attachments.0"]
}

Каждый файл нужно прикрепить в отдельном поле, имя которого соответствует ключу из map.

В REST API все параметры для создания игрушки указываются проще:

wys0d6oukumveshtzkskk5scuok.png

Версионирование

GraphQL использует одну версию endpoint. Изменения вносятся в схему без явного версионирования API, что упрощает развитие.

REST API нужно версионировать для безопасных изменений. Обычно это делается в URL, например: http://localhost:8080/v1/toys.

Ошибки и коды ответа

GraphQL всегда отвечает кодом 200 OK, даже при ошибках. Информацию об ошибке ищите в поле errors JSON-ответа. Клиент не может проверить статус по HTTP-коду и вынужден анализировать тело ответа.

REST использует стандартные HTTP-коды (400, 404, 500) для обозначения результата. Это делает обработку ошибок в REST более наглядной

Заключение

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

Тестировать GraphQL сложнее, особенно с файлами: больше настроек в запросах, чем в REST. GraphQL проще версионировать — меняем схему, и всё, а в REST приходится менять URL. Наконец, GraphQL всегда отвечает кодом 200 и сообщает об ошибках в теле ответа, а REST использует стандартные коды ошибок, что делает их более заметными.

© Habrahabr.ru