02 rest graphql

Между клиентом и сервером нужно договориться не только о формате данных (JSON, XML), но и о способе запрашивать и изменять данные. Два самых распространённых подхода — REST и GraphQL. В этом файле разберём, как каждый из них работает, на примерах с JSON. После прочтения вы будете понимать разницу и сможете уверенно переходить к практике с Postman (где мы будем использовать REST).

1. REST: идея и принципы

REST (Representational State Transfer) — это архитектурный стиль для API, опирающийся на идею ресурсов и стандартных HTTP-методов. Ресурс — это сущность, с которой можно работать: пользователь, заказ, статья, комментарий. У каждого ресурса есть адрес (URL), а действие над ним задаётся методом HTTP (GET, POST, PUT, PATCH, DELETE).

Основные принципы REST

  • Ресурсы и URL — всё, с чем мы работаем, представлено как ресурс с уникальным идентификатором. Например: /users, /users/1, /posts/5/comments.

  • HTTP-методы задают действие — один и тот же URL может означать разное в зависимости от метода:

    • GET — получить (прочитать);

    • POST — создать;

    • PUT / PATCH — изменить;

    • DELETE — удалить.

  • Без состояния (stateless) — сервер не хранит «сессию» клиента между запросами. Вся нужная информация передаётся в каждом запросе (токен, параметры).

  • Представления ресурса — клиент получает ресурс в каком-то формате (чаще всего JSON). Один и тот же ресурс может быть отдан в разных форматах при согласовании через заголовки (Content-Type, Accept).

REST не жёсткий стандарт: это набор рекомендаций. Реальные API могут чуть по-разному называть пути или использовать не все методы, но общая логика «ресурс + URL + метод» сохраняется.

2. REST на практике: ресурсы, URL и методы

Ресурсы и пути (URL)

Ресурсы обычно именуются существительными во множественном числе и отображаются в пути URL:

Ресурс
Пример URL
Описание

Список

GET /users

Все пользователи

Один по ID

GET /users/1

Пользователь с id = 1

Вложенный

GET /posts/5/comments

Комментарии к посту 5

Иерархия отражает связь: посты принадлежат пользователям, комментарии — постам. Необязательно иметь все уровни — достаточно тех, которые нужны API.

Методы HTTP и смысл в REST

Метод
Действие
Пример URL
Тело запроса

GET

Получить

GET /users/1

Не используется

POST

Создать

POST /users

JSON нового user

PUT

Заменить

PUT /users/1

JSON всего user

PATCH

Частично изменить

PATCH /users/1

JSON только полей

DELETE

Удалить

DELETE /users/1

Обычно пусто

Один URL — один ресурс. Разные операции — разные методы. Так клиент и сервер однозначно понимают, что нужно сделать.

Коды ответа

Сервер сообщает результат кодом состояния HTTP и телом ответа (часто JSON):

  • 200 OK — успешное чтение или обновление (GET, PUT, PATCH);

  • 201 Created — ресурс создан (POST), в ответе обычно возвращают созданный объект;

  • 204 No Content — успех без тела (часто после DELETE);

  • 400 Bad Request — неверные данные в запросе;

  • 401 Unauthorized — нужна авторизация;

  • 404 Not Found — ресурс не найден;

  • 500 Internal Server Error — ошибка на сервере.

В REST тело ответа при ошибках тоже часто в JSON: описание ошибки, код, список полей с ошибками.

3. REST и JSON: запросы и ответы

В REST данные в запросе и в ответе обычно передаются в JSON. Ниже — типичные примеры.

GET — только URL, тело не нужно

Запрос:

Ответ (200 OK), тело — JSON:

Запрос списка:

Ответ (200 OK):

Список может быть с пагинацией: тогда в ответе добавляют метаданные (например, total, page, perPage) или используют параметры запроса: GET /posts?page=2&limit=10.

POST — создание, тело в JSON

Запрос:

Ответ (201 Created):

Сервер добавляет id и возвращает созданный ресурс.

PUT / PATCH — обновление, тело в JSON

PUT — полная замена ресурса (передаём все важные поля):

PATCH — частичное обновление (только изменённые поля):

Ответ в обоих случаях обычно 200 OK с полным объектом ресурса в JSON.

DELETE — без тела

Ответ — 200 OK или 204 No Content, тело часто пустое.

Ошибки в JSON

При 4xx или 5xx сервер может вернуть JSON с описанием:

Клиент читает код ответа и при необходимости разбирает это тело для показа сообщений пользователю.

4. GraphQL: идея и отличия от REST

GraphQL — это и язык запросов, и способ организации API. В отличие от REST, у клиента обычно один endpoint (например, POST /graphql), а что именно нужно получить или изменить, описывается в теле запроса на специальном языке GraphQL.

Главные отличия от REST

Аспект
REST
GraphQL

Адреса

Много URL по ресурсам

Один URL (часто /graphql)

Что получаем

Ресурс целиком (или по контракту API)

Клиент сам перечисляет нужные поля и связи

Методы HTTP

GET, POST, PUT, PATCH, DELETE

Обычно только POST (запрос в body)

Запрос

URL + метод + опционально query-параметры

Текст запроса на языке GraphQL

В REST, чтобы получить пользователя и его посты, часто делают два запроса: GET /users/1 и GET /users/1/posts. В GraphQL можно описать в одном запросе: «дай пользователя 1 с полями name, email и списком постов с полями title, id» — и получить ровно эту структуру без лишних данных.

«Только то, что нужно»: экономия данных, запросов и времени

В REST сервер обычно отдаёт ресурс целиком — весь объект пользователя со всеми полями, которые заложили в API. Нужны только имя и аватар для карточки? Всё равно придут email, телефон, адрес, дата регистрации и т.д. Клиент получает лишние данные, тратит трафик и время на передачу и разбор.

В GraphQL клиент явно перечисляет, какие поля ему нужны. Сервер отдаёт только их. Никаких лишних полей — меньше объём ответа, меньше трафика (важно для мобильных и медленных сетей), меньше работы на клиенте. Итог: выше производительность и быстрее отклик, особенно когда полей в ресурсе много, а нужны единицы.

Плюс в REST для одного экрана часто нужны данные из нескольких мест: пользователь, его посты, комментарии. Каждый кусок — отдельный запрос. Несколько запросов подряд — это несколько round-trip’ов по сети, больше задержка и нагрузка. В GraphQL один запрос может описать всю нужную «глубину» данных (см. ниже про узлы). Меньше запросов — меньше время ожидания и нагрузка на сеть и сервер.

Узлы и вложенности: граф данных в одном запросе

В GraphQL запрос строится как дерево (граф) узлов. Каждый объект или список связанных сущностей — это узел. Внутри узла вы перечисляете поля (простые значения: строка, число) или переходите в следующий узел — связанный объект или список. Так получаются вложенности: пользователь → его посты → у каждого поста комментарии.

Пример структуры запроса:

  • Узел user (один пользователь) — в нём поля name, email и узел posts (список постов).

  • Внутри узла posts — у каждого поста поля id, title и при необходимости ещё узел comments (комментарии к посту).

Один запрос, одна «глубина» по графу связей — сервер сам подтянет пользователя, его посты и комментарии и вернёт один JSON. Не нужно слать несколько REST-запросов и склеивать результат на клиенте. Узлы и вложенности как раз и дают возможность описать «дай мне это, а внутри этого — вот это и вот это» в одном обращении к API.

Зачем придумали GraphQL: плюсы перед REST

GraphQL появился из-за ограничений REST при сложных клиентах (мобильные приложения, тяжёлые веб-интерфейсы): много лишних запросов, лишние данные в ответах, сложно подстроить API под каждый экран.

Основные плюсы GraphQL по сравнению с REST:

Проблема в REST
Как решает GraphQL

Overfetching (лишние данные) — REST часто отдаёт ресурс целиком. Нужны только имя и аватар пользователя, а приходит ещё email, телефон, адрес, настройки. На мобильном трафик и парсинг лишние.

Клиент явно перечисляет поля в запросе. Сервер отдаёт только то, что запросили. Меньше трафика и работы на клиенте.

Underfetching (не хватает данных) — для одного экрана нужны пользователь, его посты и комментарии к ним. В REST это несколько запросов подряд (/users/1, /users/1/posts, потом к каждому посту /posts/N/comments). Медленно, много round-trip’ов.

Один запрос с вложенной выборкой: пользователь → посты → комментарии. Сервер сам «дособирает» граф и вернёт одну JSON-структуру. Один запрос вместо цепочки.

Жёсткий контракт под все клиенты — backend отдаёт один формат для всех. Мобилке нужны одни поля, админке другие, партнёру третьи. Приходится плодить endpoint’ы (/users, /users/short, /users/for-admin) или отдавать «всё» и фильтровать на клиенте.

Один endpoint, схема общая, а каждый клиент запрашивает свой набор полей и связей. Backend не плодит десятки вариантов URL.

Версионирование — в REST при изменении формата часто вводят v2 в пути (/v2/users) или новые поля ломают старых клиентов.

В GraphQL добавляют новые поля и типы в схему, старые запросы продолжают работать. Удаление полей делают аккуратно (deprecation), клиенты успевают перейти.

Когда GraphQL особенно выгоден: много разных клиентов (веб, iOS, Android, партнёры), сложные экраны с данными из нескольких сущностей, важна экономия трафика и числа запросов (мобильные, медленные сети). Когда данных мало, экраны простые и все хотят одно и то же — REST часто проще внедрить и поддерживать.

Схема и типы

В GraphQL сервер описывает схему: какие типы есть (User, Post, Comment), какие у них поля и как они связаны. Клиент может запрашивать только то, что описано в схеме. Это даёт предсказуемость и возможность автодополнения в инструментах.

5. GraphQL на практике: запросы и мутации

Запросы к GraphQL API обычно отправляются методом POST, заголовок Content-Type: application/json, а в теле — JSON с полем query (и опционально variables). Сам текст запроса пишется на языке GraphQL.

Запрос (Query) — получение данных

Пример: получить пользователя с id = 1 и его имя, email и список постов (id и title).

Запрос GraphQL в читаемом виде (каждый узел и поле — с новой строки):

HTTP-запрос: метод POST, в теле — JSON. Поле query содержит этот же текст (при отправке можно оставить переносы строк или свести в одну строку — GraphQL это допускает).

Ответ (200 OK), тело — JSON:

Клиент получил ровно те поля, которые запросил. Если бы не указал posts, их бы не было в ответе — это уменьшает объём данных и количество «лишних» запросов.

Переменные (variables)

Чтобы не собирать строку запроса вручную, используют переменные:

Запрос с переменной:

Тело запроса (JSON):

Сервер подставит id из variables в запрос.

Мутации (Mutation) — изменение данных

Создание, обновление и удаление в GraphQL делаются через мутации (аналог POST, PUT, PATCH, DELETE в REST). В запросе указывают ключевое слово mutation, имя мутации из схемы API и аргументы (что создаём или меняем). В ответе можно запросить нужные поля изменённого или созданного объекта — так же, как в обычном запросе (query). Конкретные имена мутаций и набор аргументов у каждого API свои; их смотрят в документации или в схеме (интроспекция).

Ошибки в GraphQL

Даже при ошибке сервер часто возвращает 200 OK, а описание ошибки — в теле ответа в поле errors (массив). Поле data при этом может быть частично заполнено или null. Клиент должен проверять и data, и errors.

6. Когда что выбирать

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

Когда лучше REST

  • Простое API: ресурсы чётко выделены (пользователи, заказы, товары), один запрос — один ресурс или простая вложенность. Не нужна «графовая» выборка.

  • Публичное API для сторонних разработчиков: REST привычен, легко документировать по URL и методам, хорошо кэшируется по HTTP (GET по URL), удобно вызывать из браузера и любых инструментов.

  • Команда и экосистема: много готовых туториалов, примеров, инструментов (Postman, Swagger). Меньше порог входа.

  • Несколько разных клиентов не критично: все в основном запрашивают одни и те же форматы, overfetching/underfetching не болит.

В методичке и в практике с Postman мы работаем с REST и JSON — этого достаточно, чтобы уверенно ходить в большинство API.

Когда лучше GraphQL

  • Много клиентов с разными потребностями: веб, мобильные приложения, партнёры — каждому свой набор полей и связей. Не хочется плодить десятки REST-endpoint’ов под каждый вариант.

  • Сложные экраны: на одной странице нужны пользователь, его заказы, последние комментарии, рекомендации. В REST — цепочка запросов или жирный «агрегирующий» endpoint; в GraphQL — один запрос с вложенной выборкой.

  • Важны трафик и скорость: мобильные приложения, медленные сети. Нужно получать ровно те поля, что отображаются, без лишних данных (overfetching) и без лишних round-trip’ов (underfetching).

  • Есть силы поддерживать схему и инструменты: типизация, интроспекция, автодополнение в IDE — плюс, но нужна дисциплина по версионированию схемы и документации.

GraphQL не заменяет REST «везде»: его часто подключают для внутренних или мобильных клиентов, а публичное API оставляют REST. Оба подхода можно сочетать в одной системе.

7. Что дальше

Вы разобрались с тем, как устроены REST (ресурсы, URL, методы HTTP, обмен данными в JSON) и GraphQL (один endpoint, запросы и мутации в теле, выбор полей клиентом). Дальше в методичке — практика: работа с REST API через Postman (следующий файл), затем переход к API вашей компании и коду.