JSON RPC
JSON-RPC 2.0 library for C++
|
A class that manages JSON RPC method handlers and processes JSON RPC requests. More...
#include <dispatcher.h>
Public Types | |
using | context_t = std::pair<std::any, nlohmann::json> |
Optional context data for method handlers. | |
Public Member Functions | |
dispatcher () | |
Class constructor. | |
dispatcher (const dispatcher &)=delete | |
dispatcher (dispatcher &&rhs)=default | |
Move constructor. | |
virtual | ~dispatcher () |
Class destructor. | |
template<typename F> | |
void | add (std::string_view method, F &&f) |
Adds a method handler f for the method method. | |
template<typename C, typename F> | |
void | add (std::string_view method, F &&f, C instance) |
Adds a method to the dispatcher with the specified instance and function. | |
template<typename F> | |
void | add_ex (std::string_view method, F &&f) |
Adds a method handler with a context parameter. | |
template<typename C, typename F> | |
void | add_ex (std::string_view method, F &&f, C instance) |
Adds a method handler with a context parameter and a class instance. | |
dispatcher & | operator= (const dispatcher &)=delete |
dispatcher & | operator= (dispatcher &&rhs)=default |
Move assignment operator. | |
nlohmann::json | process_request (const nlohmann::json &request, const std::any &data={}) |
Processes a JSON RPC request. | |
Protected Member Functions | |
virtual nlohmann::json | do_process_request (const nlohmann::json &request, const std::any &data, bool is_batch, std::uint64_t unique_id) |
Processes a single, non-batch JSON RPC request. | |
virtual nlohmann::json | invoke (const std::string &method, const nlohmann::json ¶ms, const dispatcher::context_t &ctx, std::uint64_t unique_id) |
Invokes a method handler. | |
virtual nlohmann::json | process_batch_request (const nlohmann::json &request, const std::any &data, std::uint64_t unique_id) |
Processes a batch request. | |
virtual void | request_failed (const nlohmann::json &request_id, const std::exception *e, bool is_batch, std::uint64_t unique_id) |
Invoked when a request fails. | |
virtual void | request_parsed (const jsonrpc_request &request, const std::any &data, std::uint64_t unique_id) |
Invoked after the request has been parsed. | |
Private Types | |
using | handler_t = std::function<nlohmann::json(const context_t& ctx, const nlohmann::json& params)> |
Method handler type. | |
Private Member Functions | |
void | add_internal_method (std::string_view method, handler_t &&handler) |
Adds a method handler for the specified method. | |
template<typename C, typename F, typename Context, typename Args> | |
constexpr auto | create_closure (C inst, F &&f) const |
Creates a closure for invoking a member function with JSON parameters. | |
Private Attributes | |
std::unique_ptr< dispatcher_private > | d_ptr |
Pointer to the implementation (Pimpl idiom). | |
Friends | |
class | dispatcher_private |
A class that manages JSON RPC method handlers and processes JSON RPC requests.
The dispatcher class allows adding method handlers for JSON RPC methods and processes JSON RPC requests. It supports adding plain functions, static class methods, lambda functions, and member functions as handlers. The handlers can accept and return values that can be converted to and from nlohmann::json
values.
The dispatcher class provides the following functionalities:
add
method. The handler function can accept any number of arguments as long as they can be converted from a nlohmann::json
value. The handler function can also return any type that can be converted to a nlohmann::json
value.std::exception
, the exception will be caught and an appropriate JSON RPC error response will be returned. Definition at line 77 of file dispatcher.h.
using wwa::json_rpc::dispatcher::context_t = std::pair<std::any, nlohmann::json> |
Optional context data for method handlers.
This type alias defines a context data type that can be passed to method handlers. The context data is a pair of two values:
std::any
object that is passed to the process_request()
method;nlohmann::json
object that contains additional fields extracted from the JSON RPC request. Definition at line 87 of file dispatcher.h.
|
private |
Method handler type.
This type alias defines a method handler function that takes two parameters:
ctx
: An additional parameter that can be used to pass additional information to the handler.params
: A JSON object containing the parameters for the method.The handler function returns a JSON object as a result.
This type alias is used to define the signature of functions that handle method calls in the dispatcher.
Definition at line 103 of file dispatcher.h.
wwa::json_rpc::dispatcher::dispatcher | ( | ) |
Class constructor.
Definition at line 14 of file dispatcher.cpp.
|
virtualdefault |
Class destructor.
|
delete |
|
default |
Move constructor.
rhs | Right-hand side object. |
|
inline |
Adds a method handler f for the method method.
F | Type of the handler function f. |
method | The name of the method to add the handler for. |
f | The handler function. |
This overload is used to add a plain function, a static class method, or a lambda function as a handler.
Internally, the handler is a function that accepts a nlohmann::json
as its argument and returns a nlohmann::json
value. However, the handler function can accept any number of arguments, as long as they can be converted from a nlohmann::json
value. The same is true for the return value: it can be any type that can be converted to a nlohmann::json
value (or void
). Of course, the handler can accept and/or return nlohmann::json
values directly.
"params": {"subtrahend": 23, "minuend": 42}
, the handler function must accept a single argument of a struct type: subtract_params
, you must define the conversion function yourself. The easiest way is to use a macro: nlohmann::json
argument and parse it as needed, like this: nlohmann::json
argument, it will accept any parameters. For example: nlohmann::json
value. If there is no default conversion available, the handler can either return a nlohmann::json
value directly, or use a custom to_json()
function.void
, it will be automatically converted to null
in the JSON response.std::exception
), the exception will be caught, and the error will be returned in the JSON response:json_rpc::exception
will be converted to a JSON RPC error object using json_rpc::exception::to_json();std::exception
will be converted to a JSON RPC error object with code -32603 (exception::INTERNAL_ERROR
) and the exception message (what()) as the error message. Definition at line 203 of file dispatcher.h.
|
inline |
Adds a method to the dispatcher with the specified instance and function.
C | The type of the class instance. |
F | The type of the function to be added. |
method | The name of the method to be added. |
f | The function to be added, which will be bound to the instance. |
instance | The instance of the class to which the function belongs. This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. |
This template method allows adding a method to the dispatcher by binding a member function of a class instance. It uses function traits to deduce the argument types and creates a closure that is then added to the internal method map.
Definition at line 221 of file dispatcher.h.
|
inline |
Adds a method handler with a context parameter.
F | The type of the handler function. |
method | The name of the method to add the handler for. |
f | The handler function. |
This method allows adding a handler function with an additional context parameter. The context parameter can be used to pass additional information to the handler function. The handler function can accept any number of arguments as long as they can be converted from a nlohmann::json
value. The same is true for the return value: it can be any type that can be converted to a nlohmann::json
value (or void
).
This overload is used to add a plain function, a static class method, or a lambda function as a handler.
See process_request()
for more details on the extra parameter.
Definition at line 263 of file dispatcher.h.
|
inline |
Adds a method handler with a context parameter and a class instance.
C | The type of the class instance. |
F | The type of the handler function. |
method | The name of the method to add the handler for. |
f | The handler function. |
instance | The instance of the class to which the function belongs. |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
This method allows adding a class method handler with an additional context parameter. The context parameter can be used to pass additional information to the handler function. The handler function can accept any number of arguments as long as they can be converted from a nlohmann::json
value. The same is true for the return value: it can be any type that can be converted to a nlohmann::json
value (or void
).
Definition at line 286 of file dispatcher.h.
|
private |
Adds a method handler for the specified method.
method | The name of the method. |
handler | The handler function. |
This method registers a handler function for a given method name. The handler function will be invoked when a request for the specified method is received.
Definition at line 18 of file dispatcher.cpp.
|
inlineconstexprprivate |
Creates a closure for invoking a member function with JSON parameters.
C | The type of the class instance (can be a pointer or null pointer). |
F | The type of the member function (if C is not std::nullptr_t ) or the function. |
Context | The type of the context parameter that can be passed to the member function (can be void or context_t ). |
Args | The type of the arguments tuple. |
inst | The instance of the class (can be a pointer or null pointer). |
f | The member function to be invoked. |
This method creates a closure (lambda function) that can be used to invoke a member function with arguments extracted from a JSON object.
The closure performs the following steps:
nlohmann::json
, it directly passes the JSON object to the member function.exception::INVALID_PARAMS
code.The invoke_function
method is used to invoke the member function with the extracted arguments.
The std::apply
function is used to unpack the tuple and pass the arguments to the member function.
Compile-time checks ensure that the code is type-safe and that certain conditions are met before the code is compiled. This helps catch potential errors early in the development process and improves the overall robustness of the code.
Definition at line 453 of file dispatcher.h.
|
protectedvirtual |
Processes a single, non-batch JSON RPC request.
request | The JSON RPC request as a JSON object. |
data | Additional information to pass to the method handlers as a part of the context. |
is_batch | Indicates whether the request is a part of a batch request. |
unique_id | The unique request ID. |
This method processes a JSON RPC request by invoking the method handlers for the specified method. If the request is a batch request, it will call process_batch_request()
.
Definition at line 34 of file dispatcher.cpp.
|
protectedvirtual |
Invokes a method handler.
method | The name of the method to invoke. |
params | The parameters for the method. |
ctx | The context to pass to the method handlers. |
unique_id | The unique request ID. |
This method finds the handler for the specified method and invokes it with the provided parameters.
exception | If the method is not found or the invocation fails. |
Definition at line 100 of file dispatcher.cpp.
|
delete |
|
default |
Move assignment operator.
rhs | Right-hand side object. |
|
protectedvirtual |
Processes a batch request.
request | The batch request as a JSON array. |
data | Additional information to pass to the method handlers as a part of the context. |
unique_id | The unique request ID. |
This method processes a batch request by invoking the method handlers for each request in the batch.
Definition at line 68 of file dispatcher.cpp.
nlohmann::json wwa::json_rpc::dispatcher::process_request | ( | const nlohmann::json & | request, |
const std::any & | data = {} ) |
Processes a JSON RPC request.
request | The JSON RPC request as a nlohmann::json object. |
data | Optional data that can be passed to the handler function (only for handlers added with add_ex()). |
nlohmann::json
object. If the request is a Notification, it will be of the discarded_t type.This method processes a JSON RPC request.
Exceptions derived from std::exception
thrown by the handler function are caught and returned as JSON RPC error responses:
json_rpc::exception
will be converted to a JSON RPC error object using json_rpc::exception::to_json()
. std::exception
will be converted to a JSON RPC error object with code -32603
(exception::INTERNAL_ERROR) and the exception message as the error message.For the handlers that accept the context
parameter, this method will construct the context as follows:
data
parameter will be passed as the first element of the context
tuple.context
tuple as a JSON object.For example, given this request:
and data
set to std::string("some_data")
, the context
parameter passed to the handler will be a pair of values:
std::string("some_data")
as std::any
;nlohmann::json
representing the object { "auth": "secret", "user": "admin" }
. Definition at line 23 of file dispatcher.cpp.
|
protectedvirtual |
Invoked when a request fails.
request_id | JSON RPC request ID. |
e | Exception that is the reason for the failure. |
is_batch | Whether this is a top-level batch request. |
unique_id | Unique request ID. |
Definition at line 111 of file dispatcher.cpp.
|
protectedvirtual |
Invoked after the request has been parsed.
request | The parsed request. |
data | Additional information to pass to the method handlers as a part of the context. |
unique_id | The unique request ID. |
Definition at line 95 of file dispatcher.cpp.
|
friend |
Definition at line 90 of file dispatcher.h.
|
private |
Pointer to the implementation (Pimpl idiom).
This unique pointer holds the private implementation details of the dispatcher class. It is used to hide the implementation details and reduce compilation dependencies.
Definition at line 411 of file dispatcher.h.