GraphQL или REST: Какой API выбрать, чтобы не прогадать?
Привет, хабровчане!
Я Дима, Backend-разработчик на Go.
Расскажу о GraphQL, сравню с REST. Разберемся в плюсах и минусах каждого подхода к проектированию API. Выбираем лучший для вашего проекта!
Распространенность и интеграция
В 2015 году Facebook представил GraphQL. С тех пор эта технология набирает популярность, но REST остается лидером. По данным Postman на 2024 год, GraphQL используют 29% разработчиков, REST — 90%.

Если заранее неизвестны потребители 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:

Запрос к REST API:

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

В поле 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 все параметры для создания игрушки указываются проще:

Версионирование
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 использует стандартные коды ошибок, что делает их более заметными.