REST API vs GraphQL: в чём между ними разница

Сегодня в среде разработчиков часто продвигают GraphQL в качестве замены REST, хотя обе технологии можно использовать одновременно. В этой статье Екатерина Саяпина, Product Owner личного кабинета платформы МТС Exolve (входит в экосистему МТС), рассмотрит интерфейсы подробнее, чтобы понять, как выбрать подходящее решение под каждый конкретный проект. Подробности — под катом.

7da45af361575709525101dda1229f23.png

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

© Habrahabr.ru