JSON-RPC is a protocol that allows you to execute some commands remotely, pass arguments to these commands and get the results back. Both requests and responses are JSON encoded.

Here is a typical request-response interaction that calls a procedure that adds two numbers:

Request: {"jsonrpc": "2.0", "method": "add", "params": [12, 34], "id": 1}
Response: {"jsonrpc": "2.0", "result": 36, "id": 1}

A request must pass the method name, parameters and command ID which is a sequence number. The server is going to reply with the same ID in the response. The response has a result, error (if any) and ID. Here is a typical failure case, calling a non-existing method:

Request: {"jsonrpc": "2.0", "method": "blah", "id": 10}
Response: {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Procedure not found."}, "id": 10}

These days, REST is quite popular for implementing web services. For some use cases, however, the REST paradigm is not well suited and the JSON-RPC approach may play better. Note, JSON-RPC messages can be transported over many lower level protocols, like plain TCP, HTTP, Websocket, etc.

Now let’s look how Mongoose implements it. For client side JSON-RPC, Mongoose provides the following API:

int mg_rpc_create_request(char *buf, int len, const char *method,
const char *id, const char *params_fmt, ...);
int mg_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
int max_toks, struct mg_rpc_reply *,
struct mg_rpc_error *);

For the server side:

int mg_rpc_create_reply(char *buf, int len, const struct mg_rpc_request *req,
const char *result_fmt, ...);
int mg_rpc_create_error(char *buf, int len, struct mg_rpc_request *req,
int code, const char *message, const char *fmt, ...);
int mg_rpc_create_std_error(char *buf, int len, struct mg_rpc_request *req,
int code);
int mg_rpc_dispatch(const char *buf, int, char *dst, int dst_len,
const char **methods, mg_rpc_handler_t *handlers);

Now, let’s look at the simple example, published in our GitHub Repo. It implements a JSON-RPC server with a single method sum that adds numbers that are passed as parameters. To build and start an example, you need a UNIX or Mac workstation with development tools installed:

$ git clone https://github.com/cesanta/mongoose.git
$ cd mongoose/examples/json_rpc_server
$ make
$ ./json_rpc_server
Starting JSON-RPC server on port 8000

This starts a JSON-RPC over HTTP server on port 8000 which expects JSON-RPC commands. If we point a browser at http://localhost:8000, we’ll get an error response from the JSON-RPC server, which is expected because a browser does not send a valid JSON-RPC request:

Mongoose Embedded Web Server Example

However, we can use the curl utility to send properly formatted JSON-RPC commands:

$ curl -d '{"id":1,method:"sum",params:[22,33]}' 127.0.0.1:8000
{"jsonrpc":"2.0","id":1,"result":55}

Hope you enjoyed the enjoyed this example.

Check out Mongoose on Github and browse many more examples!

To contact: send us a message or ask on the developer forum.