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:
Список
GET /users
Все пользователи
Один по ID
GET /users/1
Пользователь с id = 1
Вложенный
GET /posts/5/comments
Комментарии к посту 5
Иерархия отражает связь: посты принадлежат пользователям, комментарии — постам. Необязательно иметь все уровни — достаточно тех, которые нужны API.
Методы HTTP и смысл в REST
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
Адреса
Много 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:
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 вашей компании и коду.