Подробнее о JSON RPC
Не хочу разводить очередной холивар на эту тему. Поэтому, если вкратце, то GraphQL — это сложно, RPC — быстро, REST — некий медиум, но не хватает batch-запросов. И если у вас небольшое приложение или микросервис, то rpc, он же “вызов удаленной процедуры”, может оказаться гораздо лучше и экономичнее для вашей архитектуры, особенно если она основана на микросервисном подходе.
На моей практике это решение оказалось достаточно удобным и простым, но при этом мощным и расширяемым. И меня сильно удивило, что в мире node.js оно применяется крайне редко.
Суть подхода достаточно примитивна
Запрос включает в себя 4 поля:
- jsonrpc — всегда будет “2.0”, указывает версию протокола.
- method — название метода (функции), который нужно вызвать.
- params — опциональное поле, нагрузка к вызову (аргументы функции).
- id — опциональное поле, уникальный идентификатор вызова. Если вы хотите получить значение от вызванной функции, то вы должны сгенерировать id на стороне клиента и при ответе вы сможете понять, на какой именно вызов пришел ответ, сопоставив id ответа.
Если вы не отправили id, то это означает, что ответ вас не интересует и от сервера вы ничего не получите. Такой вызов называется нотификацией.
Ответ может иметь следующие поля:
- jsonrpc — всегда будет “2.0”, указывает версию протокола.
- result — тело ответа (возвращаемое значение функции).
- id — уникальный идентификатор ответа. Он нужен для того, чтобы клиент мог сопоставить, на какой запрос он получил ответ.
- error — в случае ошибки вместо result, вы получите поле error, содержащее в себе code (код ответа: по протоколу их может быть шесть) и message (человекопонятное описание ошибки).
Вишенка на торте — это Batch-запрос!
Это означает, что мы можем слепить несколько отдельных ajax запросов в один и отдать его серверу в виде массива запросов. А при получении по заданным id мы поймем, на какой запрос получили ответ.
Небольшая тонкость!
Учтите, что по протоколу сервер не гарантирует последовательность элементов в ответе, например:
Будет считаться вполне нормальным ответом, т.к. время выполнения функций разное, и сервер заполняет массив ответами по мере их асинхронного выполнения.
Поэтому клиент сам должен промапить ответ и сопоставить id каждого элемента в ответе с запросом.
Давайте уже писать код!
Поскольку в последнее время я пишу на node.js и готового решения, которое бы полностью меня устроило, я не нашел, то я решил запилить простой JSON-RPC роутер для express.js без каких либо зависимостей.
В документации к пакету базовые примеры уже рассмотрены. Давайте придумаем вариант посложнее.
Например, создадим сервер с тремя методами, которые будут получать данные по http от другого ресурса. Каждый метод будет проверять, что пользователь ввел валидные параметры, затем выполнять тело метода и логировать результат выполнения в файл.
Сначала мы создадим папку с файлами, инициализируем проект и подключим к нему зависимости.cd /path/to/your/proj
mkdir medium-json-rpc
cd medium-json-rpc
yarn init -y
touch index.js
yarn add express axios body-parser express-json-rpc-router
У нас имеется три основных объекта:
methods — наши JSON-RPC методы, функции которые реализуют основную логику. Это могут быть ваши контроллеры.
beforeMethods (опциональные) — хук, который будет вызван перед выполнением метода. Здесь вы можете валидировать переданные параметры и выкидывать ошибки, которые попадут в вышестоящий обработчик. Название хука должно совпадать с названием метода, к которому этот хук относится, иначе будет вызвано исключение с сообщением, содержащим информацию о том, какой хук был назван неправильно.
afterMethods (опционально) — хук, который по своей логике похож на предыдущий. Разница только в том, что он будет вызван после выполнения метода и в качестве второго параметра получит результат выполнения. Может быть удобен для логгирования запросов.
Также предоставлен callback (onError) — функция, в которую будет передана ошибка, если она случилась. Тут можно удобно подключить логгер ошибок вроде sentry.io.
Обратите внимание, что bodyParser вызван перед роутером. Можете использовать другой вариант парсинга тела запроса, главное, чтобы в req.body мы получили параметры запроса в формате JSONRPC.
Библиотека в стадии разработки, так что если у вас есть пожелания или идеи, смело пишите в комментариях или открывайте github issues.
Всем хорошего настроения!
Популяризация JSON-RPC (часть 1)
Для передачи данных по сети есть хорошо зарекомендовавшие себя стандарты. Среди основных: SOAP, gRPC, AMQP, REST, GraphQL.

При создании вебсайтов малой, средней и большой сложности с потоками данных к бэкенду и обратно в JSON формате обычно используются последние два с их вариантами. Верней, только варианты, потому что REST и GraphQL — ресурсо-ориентированные стандарты. Это как бы просто перенос элементарной работы с базой данных на клиента (хотя под «ресурсом» может пониматься и абстракция). Обычно таких запросов не больше трети от всего бэкенд API.
Попытка сделать весь API максимально RESTful страшно раздувает код и грузит сеть. Потому что остальные две трети запросов — в форме команд на бэкенд проделать какие-то действия, слабо отображающиеся на CRUD над некими ресурсами. И вариантов послать такие запросы достаточно много. Даже, чересчур.
GET, POST, PUT, PATCH, HTTP заголовки, куки, body, данные форм, GET query параметры, json, content-type, HTTP коды. Когда в команде несколько программеров, и у каждого свой взгляд на мироустройство, довольно быстро это превращается в винегрет. Даже один фулстэк разработчик часто оказывается в тупике перед всем этим месивом параметров, глаголов и существительных RESTlike API в непонимании как дальше с этим жить.
Всё это привело к созданию простой и понятной, но с моей точки зрения сильно недооцененной спецификации JSON-RPC (https://www.jsonrpc.org/specification), которая отделяет бизнес-логику клиент-серверного запроса от самого сетевого протокола (HTTP) с его богатым, но не всегда нужным внутренним миром.
В JSON-RPC все запросы стандартизовано идут через HTTP POST в форме JSON объекта (в принципе, JSON-RPC 2.0 — это транспорто-независимый протокол, но мы рассматриваем наиболее частое его употребление). Обмен данными строгий и понятный. В запросе есть method и params . Method играет роль эндпойнта/команды, params — параметров. Ответы сервера приходят примерно в таком же виде.
RPC означает Remote procedure call, то есть, на бэкенд посылается команда о выполнении некоего кода. Команда по смыслу и предназначению может быть любой. В этом отличие RPC от REST, ограниченного четырьмя действиями CRUD на неких ресурсах.
JSON в названии означает, что обмен информацией между клиентом и сервером (микросервисами) идет через данные JSON формате.
Подробней о JSON-RPC можно прочитать, например, тут — https://habr.com/ru/post/441854/ или во многих других местах. Ничего сложного. В данной статье я хотел бы сконцентрироваться именно на его плюсах, а не описании.
Также, для задумывающихся о грамотном дизайне networked API рекомендую статьи Google на эту тему — https://cloud.google.com/apis/design. Архитектура для API не менее важна, как и для самой программной системы. Есть даже такое направление — API Driven Architecture, хотя по-моему опыту сперва обычно всё-таки делается какая-то альфа версия приложения, а потом уже рефакторится и унифицируется его API.
Плюсы
JSON-RPC отделяет бизнес логику от сетевого протокола. На этом, на самом деле, можно было бы запустить фейерверк и закончить. Да, он облегчает коммуникацию между разработчиками фронта и бэка, даёт лучшую структуру и понимание данных, простоту в разработке, протоколо-независимость, но, главное, с моей точки зрения, именно вышеуказанное отделение.
Что значит это для фронтэндера? Я обычно делаю модуль доступа к API и работаю через него:
import api from '@/api'; api.products.list(); api.users.update(userId, );
Внутри list() и update() запросы через fetch() или axios() к нужным эндпойнтам backend API. Переход на стандарт JSON-RPC несложен, может быть проведен постепенно и особо профита в кодинге не приносит, кроме отсутствия необходимости задумываться, что использовать — POST, PUT или PATCH, и как передавать параметры, как обрабатывать приходящий результат, ошибки и т.п.
Совсем другое дело бэкенд. Я большой фанат CodeIgniter 4 (далее CI), считаю его лучшим PHP фреймворком для малых и средних по размеру API, и буду говорить на его примере, но Laravel, Sping Boot, Django работают примерно по тому же принципу.
На бэке каждый запрос обрабатывается контроллером (которые сейчас по сути являются уже рудиментом MVC архитектурного шаблона времён генерации контента на сервере), в который передаются (условно) HttpRequest и HttpMessage. Один контроллер может обрабатывать несколько эндпойнтов, это прописывается в роутинге фреймворка. В контроллерах есть доступ к деталям транспортного (HTTP) протокола. Зачастую в контроллерах лежит вся бизнес логика, включая работу с БД и другими внутренними сервисами.

Что происходит, когда вы решаете сменить фреймворк, потому что нашли лучше? Вы переписываете контроллеры. Что происходит, когда ваш фреймворк радикально обновился, и вам нравятся эти новшества, вы хотите их использовать, но там много breaking change изменений? Вы переписываете контроллеры. А это бОльшая часть кода. И перейти на новую версию постепенно довольно сложно, только разом. Всё потому что ваша логика встроена в фреймворк.
А что с JSON-RPC? Там есть только один контроллер, который обрабатывает все запросы и перенаправляет их на нужные модули своим внутренним роутингом. Вот весь HTTP роутинг в CI:
$routes->post('rpc', 'JsonRpcController::index');
Вот файл внутреннего роутинга, используемый JsonRpcController-ом:
[ "transactions:list" => "Users\Transactions::list", "withdrawal:create" => "Users\Transactions::createWithdrawal", ], "utils" => [ "resources:list" => "Utils\Resources::list", "resources:update" => "Utils\Resources::update", "resources:getByKey" => "Utils\Resources::getByKey", "resources:updateByKey" => "Utils\Resources::updateByKey", "resourceCache:clear" => "Utils\Resources::clearCache", ], ]; public static function route($method) < $path = explode('.' , $method); $route = self::$routes; foreach ($path as $step) < $route = $route[$step]; >return $route; > >
Иерархическая модель в $routes задана для удобства. Функция route() берет метод запроса ( method — «плоский» вариант роута, например, users.transactions:list) и выдает соответствующий ему класс и функцию на нем.
Выбор нотации названия метода полностью за разработчиком, но мне нравятся рекомендации Google из вышеприведенной ссылки.
Utils\Resources и Users\Transactions — просто PHP классы, отвечающие за бизнес логику. Им приходят данные в виде объекта, и они отдают результат в виде объекта. Никакой связи с HTTP протоколом. Если потребуется сменить фреймворк, то нужно будет переписать только один файл — JsonRpcController.php
request->getJSON(); > catch (\Throwable $th) < return $this->response->setJSON($this->errorResponse(-32700)); > $response = null; try < // batch payload if (is_array($payloadData)) < if (count($payloadData) == 0) < return $this->response->setJSON($this->errorResponse(-32600)); > $response = []; foreach ($payloadData as $payload) < $singleResponse = $this->processRequest($payload); if ($singleResponse != null) < $response[] = $singleResponse; >> if (count($response) > 0) < return $this->response->setJSON($response); > // single request > else if (is_object($payloadData)) < $response = $this->processRequest($payloadData); return $this->response->setJSON($response); > else < return $this->response->setJSON($this->errorResponse(-32700)); > > catch (\Throwable $th) < return $this->response->setJSON($this->errorResponse(-32603, null, [ "msg" => $th->getMessage(), "trace" => $th->getTrace() ])); > > /** * Process single JSON-RPC request. * * @param object $paylod Request object * @return object Response object */ private function processRequest($payload) < if (!is_object($payload)) < return $this->errorResponse(-32700); > if (!property_exists($payload, "jsonrpc") && !property_exists($payload, "method")) < return $this->errorResponse(-32600); > $payload->context = new stdClass(); if ($this->request->currentUser ?? NULL) < $payload->context->user = $this->request->currentUser; > $route = JsonRpcRoutes::route($payload->method); if (!$route) < return $this->errorResponse(-32601, $payload->id); > list($className, $methodName) = explode("::", $route); $className = JsonRpcRoutes::$basePath . $className; $outcome = (new $className())->$methodName($payload); if (!property_exists($payload, "id") || !$outcome) < return null; >$data = [ "jsonrpc" => "2.0", "id" => $payload->id ]; return array_merge($data, $outcome); > /** * Used for generic failures. * * @param int $errorCode according to JSON-RPC specification * @return Object Response object for this error */ private function errorResponse($errorCode, $id = null, $data = null) < $response = [ "jsonrpc" =>"2.0", "error" => [ "code" => $errorCode, "message" => '' ], "id" => $id ]; if ($data) < $response["error"]["data"] = $data; >switch ($errorCode) < case '-32600': $response["error"]["message"] = "Invalid Request"; break; case '-32700': $response["error"]["message"] = "Parse error"; break; case '-32601': $response["error"]["message"] = "Method not found"; break; case '-32602': $response["error"]["message"] = "Invalid params"; break; case '-32603': $response["error"]["message"] = "Internal error"; break; default: $response["error"]["message"] = "Internal error"; break; >return $response; > >
Контроллер мог бы быть в три-четыре раза меньше, но мне захотелось реализовать требования спецификации JSON-RPC 2.0 по максимуму, в итоге половина кода — корректная обработка всевозможных ошибок. По сути же он просто берет роут из JsonRpcRoutes и вызывает соответствующий метод на нужном классе, передавая ему параметры.

Да, в бэкэнд фреймворках есть другие часто используемые сервисы — например, для упрощения доступа к данным в БД (Active records (не ORM) в CodeIgniter 4 — очень эффектное решение, генерирующее эффективный SQL, возможно, единственное, ради чего стоит использовать CI, а не чистый rpc.php как вход с вебсервера), и их надо будет адаптировать при возможном переезде, но при желании модуль бизнес-логики (Utils\Resources и Users\Transactions) можно написать на чистом PHP/Java/Python, либо самостоятельно использовать сторонние библиотеки и быть полностью независимым от фреймворка. А ведь фреймворки очень хотят привязать разработчиков к себе.
А насколько проще тестировать свои классы, а не контроллеры, насколько проще строить архитектуру приложения без ограничений фреймворка, его контекста, потока исполнения и магии.
Я уж не говорю о переиспользовании кода: вызвать из одного контроллера метод другого, чтобы применить его ответ для выдачи клиенту — задача не тривиальная. Потому что вход и выход в контроллерах — через протоколозависимые шлюзы фреймворка. Да, можно вытащить всю логику из контроллеров и использовать их как пустые обертки/прокси — но в чем тогда будет их смысл? Да и именно это и делает JSON-RPC, — в том числе.
Нынешние бэкенд фреймворки создавались когда всё еще генерировалось на сервере и клиенту посылался готовый html. Для всего этого нужны были серверные сессии, шаблонизаторы и прочие штуки серверных фреймворков. Для современных SPA-ориентированных бэкенд APIs всё это не нужно, это тяжелый груз, который часто как кандалы мешает работать с современными технологиями.
Вывод
JSON-RPC дарит разработчикам свободу.

К сожалению JSON-RPC всё еще относится к эзотерическому знанию, крутость которого понимаешь только после того как его попробуешь, а попробовать решаются только разработчики, достигшие определенного уровня усталости от жизни такой. Большинство продолжает самоделить каждый раз корявые рестоподобные велосипеды.
Я бы даже сказал, что JSON-RPC — единственный стандарт, который технически полностью можно реализовать при построении коммуникации с бэкендом в 90% современных web app и мобильных приложений (если не смотреть в сторону gRPC и экзотики). И который реально приносит пользу в DX. Попытка реализации других стандартов будет большим компромиссом (просто оставлю здесь слово «HATEOAS»).
Во второй части я остановлюсь на нескольких особенностях при работе с JSON-RPC, а именно: зачем нужны batch пакеты, аутентификация и авторизация, как видеть в DevTools / Network и логах вебсервера семантически понятную информацию о запросах, а не просто /rpc , и как стать господином бэкэнд фреймворка, а не его рабом.
В чем разница между RPC и REST?

RPC и REST – два архитектурных стиля проектирования API. API – это механизмы, которые позволяют двум программным компонентам взаимодействовать друг с другом, используя набор определений и протоколов. Разработчики программного обеспечения используют ранее разработанные или сторонние компоненты для выполнения функций, поэтому им не нужно писать все с нуля. RPC API позволяют разработчикам вызывать удаленные функции на внешних серверах, как если бы они были локальными для своего программного обеспечения. Например, вы можете добавить функцию чата в свое приложение, удаленно вызывая функции обмена сообщениями в другом приложении чата. Напротив, REST API позволяют выполнять определенные операции с данными на удаленном сервере. Например, приложение может добавлять или изменять данные сотрудников на удаленном сервере с помощью REST API.
В чем сходство систем RPC и REST?
Удаленный вызов процедур (RPC) и REST – это способы разработки API. API являются неотъемлемой частью современного веб-проектирования и других распределенных систем. С их помощью два отдельных распределенных приложения или сервиса могут взаимодействовать, не обладая информацией о внутреннем устройстве друг друга. Эти два приложения или сервиса могут не иметь практически ничего общего, за исключением обмена небольшим объемом данных.
API также являются стандартным механизмом взаимодействия внутренней части программы (логического компонента) с ее внешней частью (компонентом интерфейса). При разработке веб-страниц и веб-приложений с использованием API вместо сильной взаимозависимости обеспечивается возможность их масштабирования и изменения с меньшим переписыванием кода.
Далее мы обсудим другие сходства между RPC API и REST API.
Абстрагирование
Несмотря на то, что сетевые взаимодействия являются основной целью API, сам процесс взаимодействия на нижнем уровне упрощен для разработчиков API. Таким образом, они могут сосредоточиться на функциях, а не на технической реализации.
Связь
И REST, и RPC используют HTTP в качестве базового протокола. Самые популярные форматы сообщений в системах RPC и REST – JSON и XML. Предпочтение отдается JSON из-за его читабельности и гибкости.
Совместимость с другими языками
Разработчики могут внедрить RESTful API или RPC API на любом языке по своему выбору. Если элемент сетевого взаимодействия API соответствует стандарту интерфейса RESTful или RPC, то остальной код можно писать на любом языке программирования.
Принципы архитектуры RPC и REST
Во время удаленного вызова процедур (RPC) клиент выполняет удаленный вызов функции (также известной как метод или процедура) на сервере. Как правило, во время вызова на сервер передается одно или несколько значений данных.
В отличие от этого, клиент системы REST запрашивает у сервера выполнение действия над определенным ресурсом сервера. Такие действия ограничиваются операциями создания, чтения, обновления и удаления (CRUD), которые передаются в виде команд или методов HTTP.
RPC фокусируется на функциях или действиях, а REST – на ресурсах или объектах.
Принципы RPC
Далее мы обсудим некоторые принципы, которым обычно следуют системы RPC. Однако они не стандартизированы, как в системе REST.
Удаленный вызов
Вызов функции в RPC осуществляется клиентом на удаленном сервере так, как если бы она была вызвана локально.
Передача параметров
Клиент обычно передает параметры в серверную функцию, аналогично локальной функции.
Заглушки
Функции-заглушки существуют как на стороне клиента, так и на стороне сервера. На стороне клиента они вызывают функцию, а на стороне сервера – фактическую функцию.
Принципы REST
Принципы REST стандартизированы. REST API должны соответствовать этим принципам, чтобы их можно было классифицировать как RESTful.
Клиент-сервер
Архитектура REST типа «клиент-сервер» разделяет клиентов и серверы, и они рассматриваются как самостоятельные системы.
Фиксация состояния
Сервер не хранит никаких записей о состоянии клиента между клиентскими запросами.
Кэшируемость
Клиентские или посреднические системы могут кэшировать ответы сервера в зависимости от того, указал ли клиент такую возможность.
Многоуровневая система
Между клиентом и сервером могут существовать посредники. И клиент, и сервер ничего о них не знают и работают так, как если бы они были соединены напрямую.
Единый интерфейс
Клиент и сервер взаимодействуют с помощью стандартизированного набора инструкций и форматов обмена сообщениями в REST API. Ресурсы идентифицируются по их URL-адресам, которые называются адресами REST API.
Как функционируют RPC и REST
При удаленном вызове процедур (RPC) клиент использует команду POST по протоколу HTTP для вызова определенной функции по ее имени. Для работы RPC разработчикам на стороне клиента необходимо заранее знать имя и параметры функции.
В REST для выполнения процедур клиенты и серверы используют такие HTTP-команды, как GET, POST, PATCH, PUT, DELETE и OPTIONS. Разработчикам нужно знать только URL-адреса ресурсов сервера и не беспокоиться об именах отдельных функций.
В таблице показан тип кода, который использует клиент для выполнения аналогичных действий в RPC и REST.
Работа
RPC
REST
Комментарий
Добавление нового продукта в список товаров
POST /addProduct HTTP/1.1
Тип контента: application/json
POST /products HTTP/1.1
Тип контента: application/json
Команда POST используется в RPC для функции, а POST в REST – для URL-адреса.
Получение сведений о продукте
POST /getProduct HTTP/1.1
Тип контента: application/json
GET /products/123 HTTP/1.1
Команда POST используется в RPC для функции и передает параметр в виде объекта формата JSON. Команда GET используется в REST для URL-адреса и передает параметр в виде такого адреса.
Обновление цены на продукт
POST /updateProductPrice HTTP/1.1
Тип контента: application/json
PUT /products/123 HTTP/1.1
Тип контента: application/json
Команда POST используется в RPC для функции и передает параметр в виде объекта формата JSON. Команда PUT используется в REST для URL-адреса и передает параметр в виде такого адреса и в виде объекта формата JSON.
POST /deleteProduct HTTP/1.1
Тип контента: application/json
DELETE /products/123 HTTP/1.1
Команда POST используется в RPC для функции и передает параметр в виде объекта формата JSON. Команда DELETE используется в REST для URL-адреса и передает параметр в виде такого адреса.
Ключевые отличия от REST
Удаленный вызов процедур (RPC) и REST – это способы проектирования соответствующих интерфейсов клиентских и серверных систем для взаимодействия через Интернет. Однако их структура, реализация и основополагающие принципы различаются. Системы, разработанные с использованием REST, называются RESTful API, а системы, разработанные с использованием RPC, – это просто RPC API.
Далее приведены некоторые другие различия.
Время разработки
Технология RPC была разработана в конце 1970-х – начале 1980-х годов, в то время как термин REST впервые ввел в обиход компьютерный ученый Рой Филдинг в 2000 году.
Операционный формат
REST API имеет стандартизированный набор серверных операций благодаря методам HTTP, а RPC API нет. В некоторых реализациях RPC обеспечивается платформа для стандартизированных операций.
Формат передачи данных
REST может передавать любой формат данных и несколько форматов, например JSON и XML, в одном API.
Однако в RPC API формат данных выбирается сервером и устанавливается в процессе реализации. Вы можете использовать конкретные реализации JSON RPC или XML RPC, в то время как клиенту не предоставляется такая возможность.
Штат
В контексте API термин без фиксации состояний означает принцип проектирования, согласно которому на сервере не хранится никакая информация о предыдущих взаимодействиях клиента. Каждый запрос API обрабатывается независимо, и сервер не полагается на сохраненное состояние клиента для обработки запроса.
Системы REST всегда должны работать без фиксации состояния, а системы RPC могут как сохранять, так и не сохранять его, в зависимости от особенностей архитектуры.
Когда использовать RPC, а когда – REST
Удаленный вызов процедур (RPC) обычно используется для вызова удаленных функций на сервере, требующих результата действия. Этот сервис можно использовать, когда требуются сложные вычисления или вы хотите запустить удаленную процедуру на сервере, скрыв процесс от клиента.
Ниже перечислены действия, для которых RPC подходит наилучшим образом.
- Съемка с помощью камеры удаленного устройства.
- Использование на сервере алгоритма машинного обучения для выявления мошенничества.
- Перевод денег с одного счета на другой в системе дистанционного банковского обслуживания.
- Удаленный перезапуск сервера.
REST API обычно используется для выполнения операций создания, чтения, обновления и удаления (CRUD) объекта данных на сервере. Таким образом, REST API хорошо подходят для случаев, когда требуется единообразное представление серверных данных и структур данных.
Ниже перечислены действия, для которых REST API подходит наилучшим образом.
- Добавление продукта в базу данных.
- Извлечение данных из списка воспроизведения музыки
- Обновление адреса человека.
- Удаление записи в блоге.
Почему REST заменяет RPC?
Хотя REST веб-API сегодня считаются нормой, вызов удаленных процедур (RPC) никуда не исчез. REST API чаще всего используется в приложениях, поскольку разработчикам проще понять и внедрить его. Однако RPC все еще существует и используется, когда больше подходит для конкретного случая.
В настоящее время более популярны современные реализации RPC, такие как gRPC. В некоторых примерах использования архитектура gRPC работает лучше, чем RPC и REST. Она позволяет осуществлять потоковое взаимодействие между клиентом и сервером, а не обмен данными по схеме «запрос-ответ».
Краткое описание различий RPC и REST
RPC
REST
Система, позволяющая удаленному клиенту вызвать процедуру на сервере так, как если бы она была локальной.
Набор правил, определяющих структурированный обмен данными между клиентом и сервером.
Выполнения действий на удаленном сервере.
Операций создания, чтения, обновления и удаления (CRUD) на удаленных объектах.
Лучше всего применять
Когда требуются сложные вычисления или запуск удаленного процесса на сервере.
Когда требуется единообразное представление серверных данных и структур данных.
С фиксацией состояния или без нее.
Без фиксации состояния.
Формат передачи данных
В последовательной структуре, определяемой сервером и обязательной для клиента.
В структуре, определяемой сервером самостоятельно. В пределах одного API можно передавать различные форматы.
Как AWS обеспечивает соответствие вашим требованиям к API?
Amazon Web Services (AWS) предлагает ряд сервисов и инструментов, с помощью которых разработчики API могут создавать, запускать современные приложения и сервисы на основе API и управлять ими. Дополнительные сведения см. в статье о создании современных приложений на AWS.
Инструменты AWS, которые могут удовлетворить ваши требования к API:
- Amazon API Gateway предоставляет разработчикам возможность создавать, публиковать API и управлять ими в любом масштабе. С помощью API Gateway можно создавать REST API, оптимизированные для контейнерных микросервисных архитектур и веб-приложений.
- Elastic Load Balancing (ELB) распределяет сетевой трафик для улучшения масштабируемости приложений. Этот инструмент может маршрутизировать и балансировать трафик gRPC между микросервисами или клиентами и службами с поддержкой gRPC, что позволяет легко внедрять управление трафиком gRPC в архитектуры без изменения базовой инфраструктуры клиентов или их сервисов.
- Amazon Virtual Private Cloud (Amazon VPC) Lattice – это сетевой сервис приложений, который обеспечивает постоянное подключение, мониторинг и защиту связи между сервисами. Он автоматически масштабирует вычислительные и сетевые ресурсы для поддержки рабочих нагрузок HTTP, HTTPS и gRPC с высокой пропускной способностью.
Создайте аккаунт прямо сейчас и начните работу с REST API и RPC на AWS.
Что такое JSON-RPC?
![]()
Протоколы API, как и все в этом мире, активно развиваются. Многие компании, включая GraphQL, gRPC и Thrift, пользуются классическими API SOAP и REST. В списке этих API есть и JSON-RPC.
JSON-RPC, созданный для быстрой разработки многофункциональных сайтов, быстро стал лучшим другом разработчиков.
Давайте разберемся, что это такое, и в чем оно полезно специалистам по разработке приложений и API. Знакомство с JSON-RPC начинается с азов JSON. Так что первая глава данной статьи посвящена общей информации о JSON.
JSON – что это такое, и как оно работает
JSON – это легковесный формат обмена сообщениями, который подходит для более быстрой передачи данных. Именно поэтому он так активно используется в современной разработке.
JSON (JavaScript Object Notation, или нотация объектов JavaScript) производит многократную разбивку данных до тех пор, пока они не примут удобный для обработки вид. В основе JSON лежит JavaScript, поэтому просматривая элементы данных, вы не раз встретите строки, нулевые символы, объекты и бинарные переменные.
JSON разбивает сложные сопоставленные данные на управляемые структуры, облегчая обработку данных на многих языках программирования, и считается независимым от языка ресурсом. Его придумал Дуглас Крокфорд в 2000 году с целью упрощения взаимодействия между веб-приложениями и сервером.
Что такое JSON RPC?
JSON-RPC – это не что иное, как преемник JSON, повсеместно признанный протокол для удаленного вызова процедур (RPC — Remote Procedure Calls). Работая на уровне разработки, JSON-RPC запускает различную структуру данных, определяя задачи для приложений. Это сравнительно новый протокол с узкой областью применения.
Наборы команд, гибкость и сценарии развертывания – все работает с ограничениями. Но, тем не менее, разработчики видят в нем идеальный вариант для простой и быстрой разработки. В простых сценариях данные ограничения не являются помехой и побуждают разработчиков переходить с REST на JSON-RPC. Стоит также добавить, что:
- JSON-RPC определяет сетевые ограничения, связанные с обработкой данных.
- Легкая конструкция и быстрая обработка – все это подходит для инициации передачи данных с узлами Ethereum.
- Будучи транспортно-независимым протоколом, JSON-RPC может использовать для взаимодействия сокеты и HTTP.
- Это отличное решение для разработки решений на базе Ethereum с использованием блокчейн.
В настоящий момент предлагается 2 стандарта JSON-RPC: JSON-RPC 1.0 и JSON-RPC 2.0:
- JSON-RPC 1.0 не хватает возможностей сразу по нескольким пунктам. Отсутствие названий параметров и пояснений к ошибкам вызывает куда больше проблем, чем кажется. Скорее уж, это метод для одноранговой передачи данных.
- Обновленный JSON RPC 2.0 значительно доработали, заполнив ряд пробелов предыдущей версии. Версию 1.0. заменили клиент-серверной 2.0. Кроме того, в 2.0. появились транспортные зависимости.
Разумеется, со временем добавили именованные параметры. Поля урезали. Нет ID для уведомлений; в качестве ответа отправляется только результат/ошибка. В обновленной версии есть дополнительные расширения с информацией об ошибках.
Как пользоваться JSON RPC?
Главная функция протокола заключается в отправке клиентских запросов на сервер (при поддержке JSON-RPC). Здесь под клиентом мы подразумеваем общепринятые приложения, которые развертываются для получения запроса от удаленной системы на консолидированный метод.
Введенные параметры передаются удаленной системе в формате массива или объекта. В зависимости от используемой версии JSON-RPC, удаленная система будет отправлять в источник запроса разные итоговые значения.
Все веб-передачи через JSON-RPC унифицированы и сериализированы с помощью JSON. Запрос JSON-RPC – это вызов удаленного метода. Он состоит из 3 элементов:
- Метод. Указывает на строку, которая будет запрашиваться при вызове метода. Существует набор зарезервированных имен с префиксом ‘rpc’ – они предназначаются для внутренних вызовов RPC.
- Параметры. Второй элемент JSON-RPC (объект или массив) со значением параметра, который будет переноситься. Параметры не вызываются в каждом вызове.
- ID. Целое или строковое число, которое регулярно используется для поддержания баланса между запросами и ответами. Если на запрос нет ответа, то ID автоматически удаляется.
В запросе JSON-RPC получатель обязан вернуться к проверенному ответу на каждый полученный запрос. Добавляются 3 компонента:
- Результат – первая и важнейшая часть запроса, передающая данные, которые возвращает вызываемый метод. Его часто называют JSON-stat, и при ошибке он остается пустым.
- Ошибка – второй компонент. Появляется, если в процессе вызова что-то идет не так. В ошибке отображаются код и сообщение.
- ID ответа указывает на запрос, по которому приходит ответ. Если ответов не требуется, то JSON-RPC использует уведомление, в котором написано, что запрос был без ID. В версии 1.0 ID уведомление приходит пустым, а в версии 2.0. оно полностью отсутствует.
Плюсы от использования JSON-RPC
JSON-RPC – это довольно «умный» протокол, который предлагает своим клиентам множество плюсов:
Простая обработка
JSON-RPC намного проще, чем REST. Его легко понимают люди и машины. Здесь нет сложных команд и наборов данных, так что JSON-RPC идеально подходит для начинающих разработчиков. Этот протокол Unicode предлагает компактную командную строку. Кроме того, он способен обрабатывать данные с именованными фразами или отдельными ключевыми словами. Таким образом, JSON-RPC считается простым и понятным инструментом для работы.
Быстрое время разработки
С JSON-RPC не надо ничего придумывать. Все источники доступны и понятны. Такая простота сокращает время разработки и сроки выхода на рынок. Это самое подходящее решение для разработки приложений в сжатые сроки.
Качественный обмен информацией
JSON-RPC гарантирует своевременный, быстрый и точный обмен данными, поскольку может обрабатывать уведомления и несколько вызовов. Чтобы продолжить свою работу, ему не нужно ждать ответа от сервера или клиента. Если сделан запрос сообщения, то JSON-RPC гарантированно доставит его «адресату». Не важно, насколько сложные компоненты приложения входят в цепочку коммуникации, JSON-RPC обеспечит должный обмен информацией.
Улучшенная производительность API
С помощью JSON-RPC можно создавать API, которые не зависят от развертываемого протокола. Такая возможность крайне важна для улучшения производительности API, т.к. заменяет HTTP и TCP, а также снижает рабочую нагрузку.
Описание результатов
JSON-RPC выдает понятные результаты запроса, которые легко прочитать и обработать. Создание пакетных запросов, объяснение body в HTTP и передача параметров – все это гораздо проще реализовать через JSON-RPC.
Улучшенная передача
JSON-RPC – это очень удобный для передачи инструмент, ведь поддерживает такие платформы, как XMPP, WebSockets, SFTP, SSH и SCP. Данное разграничение позволяет разрабатывать быстрые, простые в отладке и удобные для пользователя API. Кроме того, этот протокол полностью отделяет запрошенный контент от используемого процесса передачи. А любые ошибки в запросах, данные и предупреждения передаются через полезную информацию запроса.
REST и JSON-RPC: что выбрать для разработки API?
Богатый выбор API-ресурсов – это всегда хорошо, но остановиться на каком-то одном варианте бывает не так просто. Ниже мы постараемся помочь разработчикам и объясним ключевые особенности популярных протоколов.
JSON-RPC подходит для начинающих разработчиков с ограниченным количеством ресурсов. JSON-RPC – это очень ограниченный в ресурсах протокол, который отлично выполняет свою функцию. Кроме того, если цель разработчика хоть как-то связана с технологией распределенных реестров, то единственным жизнеспособным решением станет именно JSON-RPC. С таким развертыванием не сможет справиться ни один другой протокол.
Для разработки приложений, использующих технологии распределенных реестров, требуется независимый от протокола API, и JSON-RPC отлично подходит. Он позволяет разработчикам создавать API, которые могут взаимодействовать друг с другом с помощью любого протокола.
Есть еще одна область, в которой JSON-RPC превосходит REST. В REST доступен ограниченный набор глаголов, что приводит к ошибкам при выполнении операции. При использовании REST необходимо подробно описать HTTP-метод, и на это тратится много времени. Кроме того, в REST доступны только CRUD-операции. Так что лучше отдавать предпочтение JSON-RPC.
Тем не менее JSON-RPC нельзя назвать универсальным решением для всего. Его проблема заключается во взаимозависимости. Клиенты должны быть тесно связаны с реализацией служб, поэтому вносить изменения в эту реализацию довольно сложно. При попытке изменить что-то, клиенты чаще всего ломаются.
REST решает такие задачи намного лучше. Например, API на базе REST мало того, что легко создаются, так еще и не отслеживают состояния. Этот протокол совместим с HTTP и предлагает огромное множество HTTP-библиотек. REST позволяет создавать гибкие API. Это идеальное решение для CRUD-операций.
Оба протокола имеют свои плюсы и минусы. Разработчикам необходимо принять взвешенное решение, исходя из главной цели разработки. Например, если разработчику нужны высокопроизводительные вычисления, то стоит остановиться на JSON-RPC.
Если требуется независимая разработка приложения с удобным интерфейсом, то смело выбирайте REST. Не стоит также забывать о безопасности API.
JSON-RPC, graphql, grpc
Два самых известных аналога JSON-RPC – это GraphQL и gRPC. GraphQL – это полностью адаптивная система. Она используется для точной локализации данных запроса и получения только необходимых запрашиваемых данных. Основная черта – ориентация на клиента. Сервер практически никак не участвует в веб-передаче. Клиент сам устанавливает правила для обработки запрошенных данных.
GraphQL относится к языкам запросов, а JSON-RPC относится к удаленному вызову процедур.
Еще есть gRPC – легковесный протокол с акцентом на производительность. Это обновленная версия RPC. В JSON-RPC серверы и клиенты договариваются о запрашиваемых данных, а архитектура не важна. А в gRPC, наоборот, запросы обрабатываются по готовой схеме. Этот протокол может выполняться в любой экосистеме.
JSON-RPC интегрируется с MQTT, Python и Kallithea. Для gRPC доступны такие ресурсы, как .NET, JavaScript, C++, Swift и многие другие.
Главные отличия между всеми решениями заключаются в открытости кода и удобстве для клиентов.