Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rpc.http

import rpc

Everything here is re-exported by rpc, so import rpc is enough and the names are called as rpc.*. Importing rpc.http on its own works too and reaches the same definitions.

JSON-RPC over HTTP, both ends of it. Each message, or batch, is the body of a POST, and its answer is the body of the response, so every exchange stands on its own: no connection is kept between calls, and nothing is framed.

http_handler() serves a Service from a route of an http server, and HttpClient calls a JSON-RPC service over HTTP.

The statuses on the wire follow common practice:

StatusWhen
200an answer, whether it is a result or a JSON-RPC error
204nothing to answer: a notification, or a batch of them
405a method other than POST
415a body that is not application/json in UTF-8

A JSON-RPC error never changes the status: METHOD_NOT_FOUND comes back as a 200 whose body says so. The http server’s own limits apply first, so a body over its max_body_size is refused with 413 before it reaches the service.

Re-exported by rpc.

Functions

http_handler()

rpc.http_handler(service) -> function(2):

A route handler for an http server that answers JSON-RPC with service: register it for POST on whatever path the service lives at.

import http
import rpc

def setup(server) {
  var calculator = rpc.Service()
    .on_request('add', @(params) => params[0] + params[1])

  server.post('/rpc', rpc.http_handler(calculator))
}

http.serve(setup, { port: 8545 })

Every handler of the service is given the http request in context.request, for its headers, its client’s address, or what a middleware put in its context. A request cannot be deferred, since its answer is the response to the HTTP request it came in.

Registered for every method with server.any(), the handler answers anything other than POST with 405 and an Allow header, as the other methods should be answered.

Parameters

  • service (Service) — What answers the messages.

Returns function(2): — A handler taking an HttpRequest and an HttpResponse.

Classes

HttpClient

class rpc.HttpClient

Calls a JSON-RPC service over HTTP: each call is one POST to url, and its answer is the response.

import rpc

var node = rpc.HttpClient('https://node.example.com', {
  headers: { Authorization: 'Bearer ${token}' },
  timeout: 10,
})

echo node.request('eth_blockNumber', [])

var answers = node.request_batch([
  ['eth_blockNumber', []],
  ['eth_gasPrice', []],
])

An answer is matched to its call by id, never by position, so a batch’s answers come back in the order of its calls whatever order the server sent them in.

Some servers send a JSON-RPC error with a status other than 200. When the body of such a response is a JSON-RPC answer, it is read like any other answer, and its error raises from the call. Any other status raises an RpcHttpError.

  • printable — has a @to_string(), so echo and print() show something useful

Constructor

rpc.HttpClient(url: string, options: ?dict)

Returns a new HttpClient calling the service at url.

OptionMeaning
headersheaders sent with every call, such as Authorization
timeoutthe most seconds to wait for an answer
clientthe http.HttpClient to send through

headers defaults to none. timeout defaults to nil, which leaves the wait to the http client’s own read timeout. client defaults to a new http.HttpClient; pass one for its proxy, TLS and connection settings.

Parameters

  • url (string) — Where the service is, an http: or https: URL.
  • options (?dict) — Default nil, every option at its default.

HttpClient.request()

rpc.HttpClient.request(method: string, params, timeout: ?number)

Calls method and returns its result.

Parameters

  • method (string)
  • params (list|dict|nil)
  • timeout (?number) — The most seconds to wait for the answer. Default nil, the client’s own timeout.

Returns — any: The result the service answered with.

Raises RpcError when the service answers with an error, or its answer is not a valid answer to the call.

Raises RpcHttpError when the server answers with an HTTP status that carries no answer.

HttpClient.notify()

rpc.HttpClient.notify(method: string, params)

Sends a notification: calls method and expects nothing back.

Parameters

  • method (string)
  • params (list|dict|nil) — Default nil, which sends none.

Raises RpcHttpError when the server answers with an HTTP status that carries no answer.

HttpClient.request_batch()

rpc.HttpClient.request_batch(calls: list, timeout: ?number)

Sends several requests as one batch, in one POST, and returns every answer in the order of calls.

Parameters

  • calls (list) — Each call as a pair, [method, params].
  • timeout (?number) — The most seconds to wait for the answer. Default nil, the client’s own timeout.

Returns — list: For each call, in order, the result the service answered with, or the {RpcError} it answered with. A call the service left unanswered holds an {RpcError} with code INTERNAL_ERROR saying so.

Raises ValueError when calls is empty, or a call is not a [method, params] pair.

Raises RpcError when the service refuses the batch whole, or its answer is not a batch of answers.

Raises RpcHttpError when the server answers with an HTTP status that carries no answer.

HttpClient.send()

rpc.HttpClient.send(message, timeout: ?number) -> Response|list|nil

Sends a message as it is, a Request, a Notification, or a list of them as a batch, and returns the answer as it came: a Response, a list of what the batch’s answer holds, or nil when the server answered with nothing.

Parameters

  • message (Request|Notification|list)
  • timeout (?number) — The most seconds to wait for the answer. Default nil, the client’s own timeout.

Returns Response|list|nil

Raises RpcError when the answer is not valid JSON-RPC.

Raises RpcHttpError when the server answers with an HTTP status that carries no answer.

HttpClient.to_string()

rpc.HttpClient.to_string() -> string

This client as HttpClient(url).

Returns string


2026, Richard Ore and Zuri contributors