REST API vs. GraphQL

Поскольку GraphQL был представлен как революционная альтернатива RESTful API в 2015 году, между сторонниками и противниками обоих решений ведутся дискуссии. Как и все остальное, RESTful API и GraphQL имеют свои плюсы и минусы, которые необходимо учитывать при выборе подходящих решений для каждого проекта.

И, как всегда, выбор должен зависеть от типа проекта, который вы строите. Для одного приложения RESTful API будет оправданным решением, тогда как для другого типа GraphQL будет намного лучше.

Что такое REST API?

REST API - это программный архитектурный стиль или шаблон проектирования для API, представленный в 2000 году Роем Филдингом. REST означает «передача репрезентативного состояния», что означает, что сервер передает клиенту представление о состоянии запрошенного ресурса после вызова API.

Чтобы прояснить ситуацию, разработчики Веб-студии DST Global (dstglobal.ru) советуют сначала разбратся, что такое API.

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

REST API взаимодействует с помощью HTTP-запросов с методами GET, POST, PUT и DELETE для управления данными, которые в основном используются при разработке веб-сервисов. С помощью REST API мы отправляем запрос от одного программного обеспечения к URI ресурса, а затем второе программное обеспечение повторно отправляет ресурсы как JSON, XML или HTML.

В RESTful API все считается ресурсом, то есть объектом, о котором API может предоставлять информацию. Рассмотрим Twitter, где ресурсами могут быть, например, пользователь или твит.

Графическое представление того, как работает REST API и что происходит в фоновом режиме вызова:

REST API

Клиент отправляет запрос, используя один из методов REST API, следующий ответ сервера с данными JSON, XML или HTML.

6 ограничений API RESTful.

1. Единый интерфейс - это ограничение делится на 4 элемента:

  1. стандарт URI используется для идентификации ресурса;
  2. манипулирование данными должно определяться доступными методами (GET, PUT, POST, DELETE);
  3. информативные сообщения;
  4. гиперссылки и шаблоны URI для отделения клиента от конкретной структуры URI;

2. Без сохранения состояния - каждое взаимодействие между сервером и клиентом не должно сохранять состояния. Это означает, что сервер не хранит никаких данных о предыдущем HTTP-запросе и принимает каждый запрос как новый. Если приложение требует аутентификации для выполнения некоторых данных, следующие вызовы должны содержать всю необходимую информацию для выполнения запроса, такую как данные авторизации или аутентификации.

3. Клиент-сервер - клиентская и серверная части приложения должны быть независимыми, и единственное общее для соединений должно быть URI API.

4. Cacheable - кэширование в REST API следует применять по возможности. Оно может быть реализовано как на стороне клиента, так и на стороне сервера.

5. Многоуровневая система - REST позволяет нам размещать количество серверов между клиентом, отправляющим запрос, и сервером, отвечающим на запрос. Например, аутентификация пользователя может выполняться на другом сервере, а не при получении заказов пользователей.

6. Код по запросу (необязательно) - это ограничение является параметрами, но вместо JSON или XML REST API может отвечать исполняемым кодом, таким как код виджета пользовательского интерфейса, который можно визуализировать.

Анатомия запроса REST API

Запрос REST API может состоять из 4 элементов, но не каждый из них является обязательным. Для каждого вызова API требуется конечная точка, которая является URL-адресом, который мы запрашиваем. Конечная точка состоит из корневой конечной точки и пути, который определяет запрашиваемый нами ресурс.

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

  1. GET - получить данные с сервера
  2. POST - для создания нового элемента
  3. PUT - для обновления данных
  4. DELETE - удалить элемент

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

Что такое GraphQL?

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

Для REST API - это сильная конкуренция.

В GraphQL мы отправляем запросы на сервер и возвращаем данные в формате JSON клиенту. Он был разработан для решения проблем с гибкостью и эффективностью, которые иногда возникают с REST API.

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

Еще одна особенность GraphQL - иерархический характер, что означает, что данные в запросах и ответах отражают естественные отношения между объектами. Если пользователь связан с заказами, мы можем запросить заказы пользователя внутри объекта пользователя.

Как работает GraphQL?

Когда мы используем GraphQL, нам нужно определить схемы, которые представляют собой модели данных, которые можно запросить. Схема описывает, какие поля объект имеет с типами, а также определяет, какие запросы могут быть отправлены.

Когда у нас определены схемы, мы можем сравнить их с запросами, чтобы убедиться, что мы получим ответ сервера.

Когда запрос GraphQL отправляется на сервер, он интерпретируется по схеме и разрешает данные клиента.

Запрос отправляется от клиента, проверяется в схеме, затем разрешается с источником данных и возвращается клиенту.

GraphQL может иметь три основных типа операций:

  1. query - читать данные
  2. mutation - для сохранения данных
  3. subscription - для получения данных в реальном времени

Различия между REST и GraphQL

1. Количество конечных точек

В REST API есть несколько конечных точек, и мы получаем ресурсы, вызывая разные пути для разных типов данных. Например, когда мы вызываем api.com/users, мы вызываем пользовательский ресурс, но не можем вызвать ту же конечную точку, чтобы получить все комментарии, которые пользователь написал в блоге. Для этого мы должны вызвать другую конечную точку api.com/users/:id/comments.

В GraphQL есть только одна конечная точка; обычно это api.com/graphql. Запросы определяются на основе запросов или изменений. Мы можем запрашивать разные ресурсы на одной конечной точке, просто связывая запрос.

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

RESTful API подвержен избыточной или недостаточной выборке, что является очень распространенной проблемой для этой архитектуры API.

Избыточная выборка произошла в ситуации, когда нам нужно получить больше данных, которые нам точно нужны. Например, если мы хотим просто составить список пользователей по имени пользователя, нам не нужно получать все данные о пользователях; нам просто нужны имена. В REST API невозможно получить только необходимые данные.

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

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

3.Версия

При использовании REST API иногда можно реализовать v1 или v2 в конечных точках, что означает, что создается больше версий API. Это делает код менее читаемым и удобным в обслуживании. В GraphQL мы можем легко добавлять новые поля в схему или отмечать старые как устаревшие, и в результате нет необходимости в управлении версиями.

И REST API, и GraphQL - отличные решения для API, и у обоих есть свои сильные и слабые стороны.

GraphQL позволяет избежать избыточной и недостаточной выборки, это всего лишь одна конечная точка, и ее очень легко обновить.

С другой стороны, REST API использует HTTP-кеширование, типы контента и коды состояния. Он по-прежнему очень часто используется в больших и малых проектах, но очень важно знать, как проектировать и разрабатывать REST API, чтобы сделать его эффективным и понятным.

С моей точки зрения, если вы новичок без больших знаний в REST API, безопаснее создавать GraphQL API, потому что это проще сделать правильно. Но если у вас есть время для исследований и обучения, вы можете подумать о создании своего решения с помощью REST.

А какой ваш любимый метод создания API?

REST API vs. GraphQL
Получить консультацию у специалистов DST
Напишите нам прямо сейчас, наши специалисты расскажут об услугах и ответят на все ваши вопросы.
Комментарии и отзывы экспертов
RSS
13:39
+3
Хороший обзор, спасибо. Хотелось бы в будущем почитать более продвинутую версию.
13:43
+2
Основным минусом 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 выбирают, когда:
— у серверного оборудования маленькая пропускная способность. Необходимо снизить количество ввода-вывода данных
— в одном адресе нужно объединить множество источников
— запросы пользователей различны, необходимо прорабатывать разные ответы
15:01
+2
Как по мне, не увидел никаких преимуществ GraphQL, кроме возможности менять запросы на стороне клиента, не переписывая сервер. Впрочем, не такой это и плюс.

Сдается мне, это придумали фронтедщики, чтоб не пинать бэкендщиков по каждому чиху.

Вот только мне кажется при такой свободе и отсутствии кеширования такие запросы, особенно сложные, сильно просаживают быстродействие.
15:02
+2
Плюсы GraphQL:

— Единая нотация
— Возможность указания только тех полей, что нужно
— Можно за один запрос получить данные с разных backend-ов
— Можно получать связанные данные (пользователь + его заказы, например)
— Запросы к бекендам могут параллелиться без изменения логики в клиенте

Но есть и минусы:

— Секурити, точнее отсутствие
— Своя нотация запросов
— Нельзя указать * для полей — обязательно перечислять
— Скорость ниже, чем прямой вызов (но может быть быстрее за счёт параллелизма)

Вообще для UI подход GraphQL оказался очень удобным даже не смотря на минусы.
Единая нотация

А в чем плюс? Только возня с ее описанием. В случае простых рест запросов можно вообще забить на нотации и трафик и слать объекты целиком, с посылом — все что есть в ответе есть и в объекте. В случае сложных запросов десять раз подумаешь, а не проще ли было сделать конкретный ендпоинт для этого запроса, который бы слал конкретные объекты предстваления, не завязанные на схему, а нужные только для представления.

Возможность указания только тех полей, что нужно

В REST это тоже делалось задолго до создания GraphQL. Параметр fields в конце URL.

Можно за один запрос получить данные с разных backend-ов

Обожаю этот аргумент! Вы когда-нибудь писали кастомный резолвер, который вам соберет сложный объект по нескольким микросервисам? Это одинаковая головная боль, что для REST, что для GraphQL. Только в случае последнего вам придется писать резольвер по-настоящему общего назначения, который будет работать для всех полей и связанных объектов, и потом решать проблемы производительности с этим чудом. В случае REST такие вещи хотя бы ограничивают универсальность применения одним ендпоинтом и доступными для него спидхаками и упрощениями выборки.

Можно получать связанные данные (пользователь + его заказы, например)

Да можно, вопрос какой ценой нагрузки на сервер. Вероятно, можно написать хаки для ресольвера, чтобы он какие-то случаи запросов покрывал джойнами, а не выборкой связанных данных отдельными подзапросами. Но чем такие оптимизации принципиально отличаются от создания специализированного рестового ендпоинта?

Запросы к бекендам могут параллелиться без изменения логики в клиенте

Чтобы что?
15:02
+2
Просто в REST со стандартом проблема, его по сути нет. Есть рекомендации и устоявшаяся практика. Чем Вам Method+URL+параметр не нотация?

В REST вы тоже можете собирать с многих сервисов. Некоторые даже делают это в API gateway.

А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.
15:03
+1
Просто в REST со стандартом проблема, его по сути нет. Есть рекомендации и устоявшаяся практика. Чем Вам Method+URL+параметр не нотация?

Потому что «нотация» GraphQL создана из рассчета, что у нас волшебный сервер, который одинаково эффективно возвращает запрошенные данные. И пофиг как там GraphQL ложится на внутреннюю предметную область, аппаратные ограничения, уже реализованные способы доступа к объектам. За исключением простых случаев, ситуация когда фронтендщики диктуют схему доступа к данным, пусть и прекрываясь технологией, черевата проблемами с производительностью и неоптимальной организацией хранения данных. Потому что для фронтендщика не будут видны под капотом ключи MySQL, лимиты на внешние апи, внутренная организация кэширования. И REST, на мой взгляд, куда лучше справляется как с учетом этих особенностей, так и защитой фронтеднщиков от этих ненужных деталей.

К тому же олновесная реализация нотации GraphQL для всех сущностей системы может стоить дорого. А реализация ограниченного подмножества будет по сути не особо отличаться от REST. Только вместо ендпоинтов для сущностей нужно будет создавать ресолверы для новых сущностей.

А вот возможность получить на сервер запрос всех полей и связанных с ними записей думаю сильно плохо скажется на его здоровье. Интересно посмотреть статистику отказа в обслуживании таких endpoint’ов.

Если пытаться на ендпоинте сделать логику выборки из базы как в авторезолверах, строящих запросы по аннотациям в ORM, то все может быть очень печально. А если сделать выборку вручную написанными запросами, созданными специально под конкретный флоу, то все может быть в разы лучше чем у GraphQL.
15:04
Расскажите, пожалуйста, как происходит процесс изменения схемы GraphQL. Вот, к примеру, есть система «на бою», у нее сотни клиентских приложений, у каждого клиентского приложения тысячи юзеров. И в какой-то момент какое-то поле в схеме GraphQL (скажем, идентификатор клиентского приложения, оно во всех запросах присутствует) вдруг должно быть изменено. Скажем, раньше это был простой строковый идентификатор, а теперь нужно передавать объект из двух полей: GUID и строковый идентификатор. Как это изменение должно выкатиться на прод, не задев все клиентские приложения?

Как Вы в своих реальных рабочих проектах с этим справляетесь?
Обычно это организационный процесс в первую очередь. Можно добавить новое поле, старое пометить deprecated и запланировать удаление через 1-3 года. Из минусов — бекенд одновременно поддерживает два поля. Из плюсов — обратная совместимость и контролируемый процесс перехода.

Разницы между GraphQL и REST в данном случае нету, подход и там и там применим.

Сами разработчики GraphQL как раз не поддерживают идею api versioning и смотрят в сторону mutable схемы в общем случае.
Вам может быть интересно
Мастерство, необходимое для создания производительных, масштабируемых и удобных в обслуживании программных архитектур и API, часто остается незамеченным и недооцененным. Эта статья от разработчиков ко...
Разработчики играют решающую роль в современных компаниях. Узнайте от специалист...
В мире есть много способов программирования. Но од...
Название PHP расшифровывается как гипертекстовый п...
Прежде чем мы узнаем для чего и как придумали объе...
Что такое программное обеспечение для разработки п...
В этой статье от разработчиков компании DST Global...
В этой статье разработчики компании DST Global опи...
В программировании существует такое понятие, как «...
REST API (Representational State Transfer Applicat...
Frontend- и backend-разработка тесно связаны между...

Новые комментарии

В этом году решили запустить свой первый маркетплейс-агрегатор. Выбор остановилс...
В этом году решили запустить свой первый маркетплейс-агрегатор. Выбор остановилс...
В этом году решили запустить свой первый маркетплейс-агрегатор. Выбор остановилс...

Заявка на услуги DST

Наш специалист свяжется с вами, обсудит оптимальную стратегию сотрудничества,
поможет сформировать бизнес требования и рассчитает стоимость услуг.

Адрес

Ижевск, ул. Воткинское шоссе, д. 170 Е, Технопарк Нобель, офис 1117

8 495 1985800
Заказать звонок

Режим работы: Пн-Пт 10:00-19:00

info@dstglobal.ru

Задать вопрос по почте

Укажите ваше имя
Укажите ваше email
Укажите ваше телефон