JSON-RPC (от англ. JSON Remote Procedure Call — «удалённый вызов процедур с использованием JSON») — протокол удалённого вызова процедур (RPC), в котором сообщения кодируются в формате JSON. Он определяет структуру запросов и ответов, способы передачи параметров, обработки ошибок и отправки уведомлений. Спецификация JSON-RPC не привязана к определённому транспортному протоколу: сообщения могут передаваться, в частности, через HTTP или сетевые сокеты.
Основными опубликованными версиями протокола являются JSON-RPC 1.0 и JSON-RPC 2.0. В версии 2.0 предусмотрены именованные параметры, уведомления без ответа и пакетная передача нескольких запросов.
История
Разработка JSON-RPC началась в 2004 году как попытка использовать JSON вместо XML для удалённых вызовов процедур. Первая спецификация, JSON-RPC 1.0, была опубликована в 2005 году.
В 2006 году появился рабочий проект JSON-RPC 1.1, предусматривавший, в частности, именованные параметры, расширенную обработку ошибок и описание доступных процедур. В дальнейшем обсуждались альтернативные проекты версии 1.1 и предложение JSON-RPC 1.2.
Спецификация JSON-RPC 2.0 была опубликована 26 марта 2010 года на основе предложения от 24 мая 2009 года. Её обновлённая редакция датирована 4 января 2013 года.
Принцип работы
Клиент отправляет запрос с именем метода и, при необходимости, параметрами. Сервер обрабатывает запрос и возвращает результат или сообщение об ошибке. Для сопоставления запроса и ответа используется идентификатор id. Вызов без ожидания ответа называется уведомлением (англ. notification).
В JSON-RPC 2.0 запрос представляет собой объект JSON со следующими полями:
jsonrpc— обязательная строка со значением"2.0", обозначающая версию протокола;method— обязательная строка с именем вызываемого метода;params— необязательный массив позиционных параметров или объект с именованными параметрами;id— идентификатор запроса, используемый для сопоставления с ответом. Может быть строкой, числом илиnull; значениеnullне рекомендуется. Если поле отсутствует, сообщение считается уведомлением.
Имена методов, начинающиеся с rpc., зарезервированы для системных расширений. Имена методов и параметров чувствительны к регистру.
При успешном выполнении запроса ответ содержит поля jsonrpc, result и id. При ошибке вместо result возвращается объект error. В соответствии со спецификацией 2.0 поля result и error не должны одновременно присутствовать в одном ответе.
Версии протокола
Основные различия между JSON-RPC 1.0 и JSON-RPC 2.0 приведены в таблице.
| Характеристика | JSON-RPC 1.0 | JSON-RPC 2.0 |
|---|---|---|
| Обозначение версии | Отдельное поле версии отсутствует | Обязательное поле "jsonrpc": "2.0"
|
| Параметры вызова | Поле params содержит массив
|
Необязательное поле params содержит массив или объект
|
| Уведомление | Поле id имеет значение null
|
Поле id отсутствует
|
| Формат ответа | Присутствуют оба поля: result и error; неиспользуемое равно null
|
Присутствует только одно из полей: result или error
|
| Пакетные запросы | Отдельный формат пакетного вызова не определён | Массив запросов с возможностью обработки в произвольном порядке |
Уведомления
Уведомление — запрос, на который сервер не должен отвечать. В JSON-RPC 2.0 уведомлением считается объект запроса без поля id. Даже если при обработке такого сообщения возникла ошибка, ответ не отправляется. Наличие "id": null, в отличие от JSON-RPC 1.0, само по себе не обозначает уведомление.
Пакетные запросы
JSON-RPC 2.0 позволяет передать несколько запросов и уведомлений в одном массиве JSON. Сервер может обрабатывать их в произвольном порядке, в том числе параллельно. Ответы возвращаются массивом, причём их порядок не обязательно совпадает с порядком запросов: для сопоставления используется id. На уведомления ответы не включаются. Пустой массив не считается допустимым пакетом; если пакет состоит только из уведомлений, сервер не возвращает ответ.
Обработка ошибок
При ошибке сервер возвращает объект error, содержащий целочисленный код code, строковое описание message и необязательное поле data с дополнительными сведениями. Спецификация JSON-RPC 2.0 определяет следующие стандартные коды ошибок.
| Код | Название в спецификации | Значение |
|---|---|---|
-32700
|
Parse error
|
Получены данные, не являющиеся допустимым JSON |
-32600
|
Invalid Request
|
Некорректная структура запроса JSON-RPC |
-32601
|
Method not found
|
Запрошенный метод не существует или недоступен |
-32602
|
Invalid params
|
Некорректные параметры метода |
-32603
|
Internal error
|
Внутренняя ошибка JSON-RPC |
-32099 — -32000
|
Server error
|
Диапазон, зарезервированный для ошибок сервера, определяемых реализацией |
Диапазон кодов от -32768 до -32000 зарезервирован спецификацией для предопределённых ошибок и возможного дальнейшего использования.
Примеры
Запрос и ответ в JSON-RPC 1.0
Вызов метода subtract для вычитания двух чисел:
{"method": "subtract", "params": [42, 23], "id": 1}
Ответ:
{"result": 19, "error": null, "id": 1}
Запрос и ответ в JSON-RPC 2.0
Тот же вызов с именованными параметрами:
{ "jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 1 }
Ответ сервера:
{"jsonrpc": "2.0", "result": 19, "id": 1}
Уведомление
Пример сообщения, не требующего ответа:
{"jsonrpc": "2.0", "method": "update", "params": [1, 2, 3]}
Ошибка
Ответ на вызов несуществующего метода:
{ "jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": 7 }
Пакетный вызов
Пример пакета из двух запросов и одного уведомления:
[ {"jsonrpc": "2.0", "method": "sum", "params": [1, 2], "id": 1}, {"jsonrpc": "2.0", "method": "notify", "params": ["done"]}, {"jsonrpc": "2.0", "method": "subtract", "params": [8, 3], "id": 2} ]
Возможный ответ, в котором порядок результатов отличается от порядка запросов:
[ {"jsonrpc": "2.0", "result": 5, "id": 2}, {"jsonrpc": "2.0", "result": 3, "id": 1} ]
Все приведённые примеры иллюстрируют формат сообщений; набор доступных методов определяется конкретной службой, а не самим протоколом.
Передача данных и безопасность
Спецификация JSON-RPC 2.0 определяет формат сообщений независимо от транспортного механизма. В частности, JSON-RPC используется при обмене сообщениями через HTTP, WebSocket и потоки ввода-вывода. Конкретная реализация определяет способ организации соединения и разграничения сообщений в транспортном потоке.
Сам по себе JSON-RPC не предоставляет механизма аутентификации, авторизации или защиты транспортного соединения. Эти задачи должны решаться средствами используемого транспорта и приложения.
Применение
JSON-RPC используется, в частности, в следующих технологиях:
- Language Server Protocol (LSP) — протокол взаимодействия редакторов кода и интегрированных сред разработки с языковыми серверами, предоставляющими автодополнение, поиск определений и другие функции.
- Ethereum — интерфейс JSON-RPC применяется для взаимодействия программ с узлами сети, получения данных блокчейна и отправки транзакций.
- Model Context Protocol (MCP) — протокол взаимодействия приложений с инструментами и источниками данных для систем искусственного интеллекта; использует формат сообщений JSON-RPC 2.0.
Реализации
Для JSON-RPC существуют клиентские и серверные библиотеки на разных языках программирования. В числе примеров:
- .NET — StreamJsonRpc, библиотека для обмена сообщениями JSON-RPC 2.0 через потоки, каналы и WebSocket;
- JavaScript и TypeScript — vscode-jsonrpc, библиотека, применяемая в реализации Language Server Protocol;
- Python — jsonrpcserver, библиотека для обработки запросов JSON-RPC 2.0;
- Rust — jsonrpsee, асинхронная клиентская и серверная библиотека с поддержкой HTTP и WebSocket;
- Go — пакет стандартной библиотеки
net/rpc/jsonrpc, реализующий JSON-RPC 1.0, но не 2.0.