7.12.1. JSONRPC-01 — Building Requests, Parsing Responses
This tutorial covers the client side of daslib/jsonrpc: building
outgoing JSON-RPC 2.0 requests, notifications, and §6 batches, then
parsing the responses you get back.
7.12.1.1. Setup
Import the module:
require daslib/jsonrpc
7.12.1.2. Building a request
make_request(method, params_json, id) builds a JSON-RPC 2.0 request
as a single-line string. The params_json argument is a pre-serialized
JSON value — pass "null" for no params, or any valid JSON literal,
object, or array. The id may be int or string:
let req1 = make_request("echo", "[\"hello\"]", 1)
// → {"jsonrpc":"2.0","id":1,"method":"echo","params":["hello"]}
let req2 = make_request("status", "null", "call-7")
// → {"jsonrpc":"2.0","id":"call-7","method":"status","params":null}
7.12.1.3. Notifications
A notification omits the id field. Per JSON-RPC 2.0 §4.1, the server
MUST NOT send a response. Use these for fire-and-forget side effects:
let notif = make_notification("log", "\{\"msg\":\"ready\"}")
// → {"jsonrpc":"2.0","method":"log","params":{"msg":"ready"}}
7.12.1.4. Building a §6 batch
make_batch(messages) wraps an array of pre-built request /
notification strings as a JSON array. The server returns an array of
responses, with notification entries suppressed:
let entries <- [
make_request("status", "null", 10),
make_request("echo", "[1, 2, 3]", 11),
make_notification("log", "\{\"level\":\"info\"}")
]
let batch = make_batch(entries)
7.12.1.5. Parsing a success response
parse_response(line) returns a ParsedResponse struct. Check
is_success to distinguish {"result":...} from {"error":...}:
let wire = "\{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":[\"hello\"]}"
let r = parse_response(wire)
// r.is_success = true
// r.id_str = "1"
// r.result_json = ["hello"]
7.12.1.6. Parsing an error response
Error responses populate error_code, error_msg, and optionally
error_data. Standard codes are constants: PARSE_ERROR,
INVALID_REQUEST, METHOD_NOT_FOUND, INVALID_PARAMS,
INTERNAL_ERROR:
let wire = "\{\"jsonrpc\":\"2.0\",\"id\":1,\"error\":\{\"code\":-32601,\"message\":\"method not found\"}}"
let r = parse_response(wire)
// r.is_success = false
// r.error_code = -32601 (matches METHOD_NOT_FOUND)
// r.error_msg = "method not found"
7.12.1.7. Parsing a batched response
parse_response_batch detects whether the wire was a single response
or a JSON array. For batches, is_batch=true and responses[]
holds one entry per array element:
let wire = "[\{\"id\":10,\"result\":\"ok\"},\{\"id\":11,\"error\":\{\"code\":-32602,\"message\":\"bad\"}}]"
let pb = parse_response_batch(wire)
for (entry in pb.responses) {
if (entry.is_success) print("[{entry.id_str}] result: {entry.result_json}\n")
else print("[{entry.id_str}] error {entry.error_code}: {entry.error_msg}\n")
}
7.12.1.8. Running the tutorial
daslang.exe tutorials/jsonrpc/01_request_response.das
Full source: tutorials/jsonrpc/01_request_response.das
7.12.1.9. See also
Next: JSONRPC-02 — Implementing a Server with dispatch_line — implementing a server with
dispatch_lineJSONRPC-03 — §6 Batches: Many Messages in One Wire — §6 batches end-to-end
JSON-RPC 2.0 envelope + parser, transport-agnostic — module reference