Текстовые RPC: JSON-RPC, SOAP, GraphQL
RPC-стиль API
RPC (Remote Procedure Call) — стиль API, при котором клиент вызывает функцию (метод) на удалённом сервере, передавая параметры и получая результат. В отличие от REST, где в центре внимания ресурсы и глаголы HTTP, в RPC в центре внимания действие (вызов метода).
RPC-стиль можно разделить на две большие группы:
- Текстовые (небинарные) RPC — протоколы, использующие текстовые форматы (JSON, XML) для передачи данных.
- Бинарные RPC — протоколы, использующие бинарные форматы сериализации (например, gRPC).
Текстовые RPC
Текстовые RPC — это протоколы, которые используют текстовые форматы для представления запросов и ответов: JSON, XML и другие.
Отсутствие привязки к конкретному формату и транспорту — их ключевое свойство. Они могут работать поверх HTTP, WebSocket, очередей сообщений и т. д., что делает их гибкими для разных сценариев интеграции.
К типичным представителям текстовых RPC относятся:
- JSON-RPC
- SOAP (и его предшественник XML-RPC)
- GraphQL — с некоторыми оговорками его тоже относят к этой группе.
JSON-RPC

JSON-RPC — это протокол, который описывает, как передавать запросы и ответы в формате JSON.
Структура запроса. При работе поверх HTTP используется один и тот же endpoint и один глагол (обычно POST). Всё, что нужно для вызова, указывается внутри тела запроса:
- jsonrpc — версия протокола (обязательное поле).
- method — имя вызываемой функции (любое, не привязано к HTTP-глаголам:
createUser,likePost,deleteи т. д.). - params — параметры вызова (JSON-объект или массив).
- id — идентификатор запроса, чтобы сопоставить его с ответом.
Структура ответа. Ответ содержит те же поля:
- jsonrpc — версия протокола.
- result — результат выполнения (при успехе).
- error — объект ошибки (при неудаче), с собственным кодом и сообщением.
- id — тот же идентификатор, что был в запросе.
Важно: при успехе и при ошибке HTTP-статус-код может быть один и тот же (200). Ответ об ошибке передаётся внутри тела JSON, а не через статус-код HTTP. Это сделано сознательно — чтобы не привязываться к HTTP.
Ключевое свойство: независимость от транспорта. Главная особенность JSON-RPC (и других текстовых RPC) — отсутствие привязки к конкретному транспортному протоколу. Поскольку вся значимая информация (метод, параметры, идентификатор) находится внутри тела запроса, а не в HTTP-глаголе или endpoint'е, такой протокол можно без изменений «переложить» на другой транспорт:
- Сегодня — поверх HTTP.
- Завтра — поверх WebSocket.
- Послезавтра — поверх очередей сообщений.
Меняется только способ доставки, сама логика вызова остаётся неизменной.
SOAP

SOAP (Simple Object Access Protocol) — ещё один представитель текстовых RPC. Идейно он похож на JSON-RPC, но использует XML в качестве формата сообщений.
Как и в JSON-RPC, используется один и тот же endpoint и один глагол (POST). Запрос и ответ вкладываются в тело HTTP-сообщения в виде XML-конверта. Внутри этого конверта, на уровне самого SOAP-протокола, передаётся вся необходимая информация:
- Какую функцию (метод) вызываем.
- Параметры вызова.
- Собственные заголовки (SOAP-headers) — структура которых строго описана в рамках протокола.
SOAP, как и JSON-RPC, не привязан к HTTP. Он может работать поверх любых транспортных протоколов — включая брокеры сообщений (JMS, AMQP и т. д.). Именно это свойство делало SOAP популярным в корпоративной среде (ESB, банки, крупный enterprise) в 2000–2010-х годах: SOAP-сервисы могли общаться напрямую через шины сообщений, не будучи привязанными к HTTP.
GraphQL

Отнесение GraphQL к RPC-стилю — холиварная тема, но спикер последовательно относит его к текстовым RPC, поскольку GraphQL, как и JSON-RPC с SOAP, формально не привязан к транспорту, хотя на практике почти всегда работает поверх HTTP.
Если смотреть на GraphQL как на протокол уровня L7+, он определяет три типа операций:
- Query — запросы на получение данных (аналог GET).
- Mutation — запросы на изменение данных (создание, обновление, удаление).
- Subscription — подписка на события от сервера (реализуется поверх WebSocket или SSE).
Первые две операции — это классический request-response (запрос и ответ передаются в теле HTTP). Subscription используется реже и даёт серверу возможность самому инициировать отправку данных.
Ключевая особенность: клиент управляет ответом. В REST каждый объект или коллекция требует отдельного endpoint'а. В GraphQL клиент сам в запросе указывает, какие объекты и какие их атрибуты он хочет получить.
Пример:
query {
pets {
name
species
}
}
Сервер возвращает ровно то, что запросили. Если из запроса убрать species, ответ будет содержать только name. Если добавить id или photo — появятся и они.
Ответ укладывается в обычное HTTP body (JSON). Это и есть то, что маркетингово называют «языком запросов» — хотя технически это просто протокол, где структура ответа определяется запросом.
GraphQL — не только протокол. Помимо транспортного протокола, GraphQL включает в себя:
- Семантику описания данных (схемы, типы, связи).
- Архитектурный паттерн или фреймворк — сервер (или GraphQL gateway), который принимает запросы, собирает данные из разных источников (REST, другие GraphQL-сервисы, SOAP, базы данных) и формирует единый ответ.
Один из самых популярных фреймворков для этого — Apollo.
Независимость от транспорта. Как и другие текстовые RPC, GraphQL не привязан к HTTP. Теоретически его можно использовать поверх WebSocket, очередей сообщений и т. д. — вся значимая информация находится в теле запроса, а не в HTTP-глаголах или endpoint'ах. Однако на практике его почти всегда используют поверх HTTP.