REST API vs GraphQL: в чём между ними разница
Сегодня в среде разработчиков часто продвигают GraphQL в качестве замены REST, хотя обе технологии можно использовать одновременно. В этой статье Екатерина Саяпина, Product Owner личного кабинета платформы МТС Exolve (входит в экосистему МТС), рассмотрит интерфейсы подробнее, чтобы понять, как выбрать подходящее решение под каждый конкретный проект. Подробности — под катом.
REST API: стандарт и его особенности
Веб-службы применяют интерфейс программирования REST (Representational State Transfer — «передача состояния представления») API для предоставления клиенту запрошенных им данных.
REST API — архитектурный стиль. Он использует HTTP-запросы для доступа к различной информации. Интерфейс работает с пятью основными запросами:
GET
PUT
POST
PATCH
DELETE
Ответы возвращает в форматах XML, YAML и JSON. С помощью REST API клиент может вносить изменения на сервер.
Запросы REST API состоят из нескольких блоков кода:
Endpoint. Элемент содержит URL — способность идентифицировать ресурс в онлайн-режиме
HTTP-method. Метод описывает тип запроса, который будет отправлен на сервер
Header. Нужен для серверов, чтобы они могли тестировать, проводить аутентификацию и кэшировать данные
Body. Тело кода содержит полезные данные для передачи на сервер
Недостатки
Основным минусом REST API считают создание множества эндпоинтов. Работать с ним — это как уточнять что-либо в разных компаниях. Нужно звонить всем по очереди.
Например, вы хотите посмотреть варианты пиццы и указываете точку /pizza. API принесёт информацию о цене, акциях и составе продукта. Но вы просили информацию о видах пиццы. Придётся постоянно прописывать конкретные адреса, а это энергозатратно для разработчиков и проблематично для пользователей.
То есть возникают проблемы с выборкой: она либо избыточна, либо недостаточна. REST не может предоставлять точные данные по запросу клиентов, потому что использует один endpoint для одного адреса.
Архитектурный стиль GraphQL позволяет сделать запросы за один раз. Клиент передаёт названия трёх мест, запрашивает нужные данные и ждёт. GraphQL выполнит все запросы и принесёт данные из разных адресов.
GraphQL: стандарт и его особенности
GraphQL — язык запросов для управления данными графов. Он использует разные виды протоколов для передачи информации. GraphQL в основном возвращает ответы в JSON.
Главное отличие GraphQL от REST API в том, что все данные клиент может выбрать всего одним запросом, даже если они будут располагаться в разных источниках. А в REST API придётся сделать выборку и извлекать их уже оттуда.
Разработчики считают GraphQL умным агрегатором, который играет роль оркестратора. Он переадресовывает фрагменты запроса на разные эндпоинты. GraphQL умеет отправлять данные поверх HTTP-протокола, Websocket и SSH. Это удобно, когда вы разрабатываете многофункциональное приложение.
GraphQL имеет три главных блока:
Queries — запросы
Schema — схема. Описание типов объектов и полей, принадлежащих каждому объекту
Resolvers — функция, отвечающая за заполнение информацией полей в схеме. Способ выполнения процедуры определяет разработчик. Например, резолвер может извлекать данные из сервера или стороннего API
Для работы с графовым языком запросов есть утилита GraphiQL. Разработчик интегрирует её с Endpoint GraphQL. Он отправляет запрос серверу на предоставление своей схемы — вы получаете интерфейс для проведения тестов и изучения запросов.
Если с формированием запросов всё понятно, давайте посмотрим основные блоки кода для схем:
Character — вид среды GraphQL
Fields (например, name и address) — поля, заполняемые в виде объекта Character. Их находят в ответе на запрос. Каждое поле возвращает то значение, которое обрабатывает
Разберём поля подробно, потому что они составляют значительную часть возвращаемой информации. Итак, они могут быть скалярного вида, объектом, типом ввода, перечисления, объединения и интерфейсом.
Например, скалярные виды — это:
String — определённые символы в коде UTF-8
Int — 32-битное целое число
Float — цифра с плавающим разделительным знаком
Boolean — логическая информация: true или false
ID — уникальный идентификатор. Нужен для повторной выборки объекта
GraphQL умеет анализировать синтаксис и проверять формы собственной схемой. Этот API может показаться сложным на стадии создания приложения, но подобное разделение на отдельные элементы — интересная возможность для анализа синтаксиса — позволяет получать чёткие ответы на запросы без дополнительных выборок, в отличие от REST API.
На что обратить внимание при выборе REST API или GraphQL
В доступных сегодня REST API вы чаще можете встретить API как список endpoints:
GET /animals/:id
GET /humans/:id
GET /animals/:id/comments
POST /animals/:id/comments
В GraphQL же не нужны URL-адреса для идентификации доступных данных в API. Вы используете GraphQL-схему:
type Query {
animal(id: ID!): Animal
human(id: ID!): Human
}
type Mutation {
addComment(input: AddCommentInput): Comment
}
type Animal { ... }
type Human { ... }
type Comment { ... }
input AddCommentInput { ... }
Если чуть вникнуть, то различия такие:
GraphQL позволяет переходить внутри одиночного запроса от точки входа к данным, следуя связям из схемы. В REST получить связанные ресурсы возможно через запросы к нескольким endpoints
В GraphQL нет отличий между полями типа Query и иными полями. То есть в запросе любое поле может работать с аргументами. В REST нет какого-то первого класса при вложенном URL
В REST запись данных вертится вокруг HTTP-методов, достаточно менять GET на POST. В GraphQL нужно менять ключевое слово в запросе
REST API зашифровывает данные и даёт множество вариантов самостоятельной аутентификации API без помощи разработчиков. GraphQL позволяет контролировать доступ к полям и операциям в запросах. Но для защиты информации придётся создавать дополнительные методы.
Из-за жёсткой структуры REST API нужно постоянно прописывать путь к данным, которые хочет получить клиент, делая выборку. При работе с GraphQL достаточно прописать запрос один раз, чтобы получить точный ответ на него. Это более гибкий инструмент для выборки.
Эндпоинты запроса GET REST API могут попасть в кэш браузера на стороне клиента, на сервере — через CDN. GraphQL не хранит кэш. Однако, если использовать инструменты Apollo или URQL, можно хранить кэш на стороне клиента.
Спецификация GraphQL не подразумевает загрузку файлов, поэтому реализация остаётся на ваше усмотрение. Есть такие варианты:
Base64: делает запрос больше и дороже для кодирования и декодирования
отдельный сервер или API
библиотека типа graphql-upload, которая реализует спецификацию многочастного запроса GraphQL
В REST API каждый код состояния — это определённый вид ответа. Клиент, обрабатывающий ответы, должен знать названия кода и значение.
У GraphQL всё проще. Неважно, что будет в ответе, «успех» или «неудача», система пропишет один код состояния — 200 ОК. Клиент использует специальные инструменты для более точной расшифровки. Все ошибки будут обработаны как часть тела в рамках объекта Errors.
Status Code | REST | GraphQL |
200 | Ok | Ok |
400 | Bad Request | - |
401 | Unauthorized | - |
Пример заказа бургера по SMS
Представьте себе процесс заказа бургеров. Кто-то уже видел этот мем про GraphQL.
Вы заходите в ресторан и заказываете чизбургер. Независимо от количества заказов (вызовов RESTful API), вы каждый раз получаете ингредиент чизбургера. Он всегда будет одинаковой формы и размера (это ответ REST).
https://api.com/cheeseburger/
С GraphQL вы можете построить его по-своему: указать, каким именно чизбургер вы хотите видеть. Сначала булочка сверху, затем котлета, солёные огурцы, лук и сыр (если вы не веган).
query getCheeseburger ($vegan: Boolean) {
cheeseburger {
bun
patty
pickle
onion
cheese @skip(if: $vegan)
}
}
Ваш ответ — это именно то, что вы хотели — ни больше, ни меньше. Затем взять и заказать бургер, отправив SMS в ресторан.
Ресторан получает SMS через омниканальную платформу МТС Exolve, заранее настроив приём подобных заказов по разным каналам.
При использовании REST вы, скорее всего, получите в ответ полные «наборы данных». Если запросите информацию для меню, ваши запросы будут такими:
запрос menu бургеров по названиям, описаниям, ингредиентам в одном запросе
запрос prices к этому меню, в другом запросе
запрос images для меню
и так далее
REST даёт вам чизбургер, который есть в меню ресторана, но GraphQL позволяет вам модифицировать его и получить именно то, что вы хотите. Для вас важно выбрать оптимальный путь и заранее спланировать возможные связки с коммуникациями, тем же SMS API.
Что использовать в работе
Итак, REST API применяют, если:
работают с небольшими программами, где нужно обрабатывать простые данные
пользователи работают с ними одинаково
нет требований к сложным запросам
GraphQL выбирают, когда:
у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
в одном адресе нужно объединить множество источников
запросы пользователей различны, необходимо прорабатывать разные ответы
REST API | GraphQL |
Поддержка версий API | Нет поддержки версий API |
Есть кэширование | Нет кэширования |
Для развёртывания использует URL-адреса | Развёртывание по HTTP с одним эндпоинтом |
Вывод ответа обычно в XML, JSON и YAML | Вывод ответа в формате JSON |
Архитектуру предоставляет сервер | Архитектуру предоставляет клиент |
Быстрая обработка ошибок | Сложная обработка ошибок |
Варианты для документации | Один документ |
Для упрощения работы требуется дорогостоящее оборудование | Возможность сшивать схемы и получать удалённые данные |
Заключение
В этой статье мы подробно указали на различия двух интерфейсов и описали варианты их использования. Теперь вы можете применить тот стиль архитектуры, который подходит для вашего приложения лучше всего. Или задействовать комбинацию, особенно когда у вас в руках очень разные по строению системы и нужна интеграция с SMS API и подобными дополнениями.
Помните:
при написании публичного API, в рамках которого вы планируете обеспечить пользователю широту действий, используйте GraphQL
при разработке frontend-приложения применяйте REST API. Если хотите избавить пользователя в публичном API от N+1 проблем, используйте REST