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 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 an extra parameter. | |
template<typename C , typename F > | |
void | add_ex (std::string_view method, F &&f, C instance) |
Adds a method handler with an extra parameter and a class instance. | |
virtual void | on_method (const std::string &method, const nlohmann::json &extra) |
Invoked right before the method handler is called. | |
virtual void | on_request (const nlohmann::json &extra) |
Invoked when a request is received. | |
virtual void | on_request_processed (const std::string &method, int code, const nlohmann::json &extra) |
Invoked after the method handler is called. | |
dispatcher & | operator= (const dispatcher &)=delete |
dispatcher & | operator= (dispatcher &&rhs)=default |
Move assignment operator. | |
std::string | parse_and_process_request (const std::string &request, const nlohmann::json &extra=nlohmann::json::object()) |
Parses and processes a JSON RPC request. | |
std::string | process_request (const nlohmann::json &request, const nlohmann::json &extra=nlohmann::json::object()) |
Processes a JSON RPC request. | |
Private Types | |
using | handler_t = std::function<nlohmann::json(const nlohmann::json& extra, 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 Extra , 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:
The dispatcher class also provides virtual methods that can be overridden in derived classes to customize the behavior when a request is received, before a method handler is called, and after a method handler is called.
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.
|
private |
Method handler type.
This type alias defines a method handler function that takes two JSON parameters:
extra
: An additional JSON object that can be used to pass extra 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 92 of file dispatcher.h.
wwa::json_rpc::dispatcher::dispatcher | ( | ) |
Class constructor.
Definition at line 12 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 192 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 210 of file dispatcher.h.
|
inline |
Adds a method handler with an extra 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 extra parameter. The extra 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 254 of file dispatcher.h.
|
inline |
Adds a method handler with an extra 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 extra parameter. The extra 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 277 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 16 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. |
Extra | The type of the extra parameter that can be passed to the member function (can be void , nlohmann::json , or convertible from nlohmann::json ). |
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 455 of file dispatcher.h.
|
virtual |
Invoked right before the method handler is called.
This method does nothing by default. It is intended to be overridden in a derived class. For example, it can start a timer to measure the method execution time.
extra | Additional information that was passed to process_request() . If extra is a JSON object, it will contain all extra fields from the JSON RPC request (in extra['extra'], see process_request() ). |
method | The name of the method to be called. |
Definition at line 51 of file dispatcher.cpp.
|
virtual |
Invoked when a request is received.
This method does nothing by default. It is intended to be overridden in a derived class. For example, it can be used to log requests or increment a counter.
extra | Additional information that was passed to process_request() . Since on_request() is called before the request is parsed, the extra` parameter will not contain fields from the request itself (i.e., `extra['extra']` will not be set). |
Definition at line 46 of file dispatcher.cpp.
|
virtual |
Invoked after the method handler is called.
This method does nothing by default. It is intended to be overridden in a derived class. For example, it can be used to stop the timer started in on_method().
method | The name of the called method. It can be empty for an invalid batch request. |
code | The result code: 0 if the method was processed successfully, or an error code if an exception was thrown (e.g., exception::INTERNAL_ERROR) or the request could not be processed (e.g., exception::INVALID_PARAMS). |
extra | Additional information that was passed to process_request() . If the request had already been successfully parsed before on_request_processed() was called, the extra parameter will contain all extra fields from the JSON RPC request (in extra['extra'], see process_request() ). |
Definition at line 56 of file dispatcher.cpp.
|
delete |
|
default |
Move assignment operator.
rhs | Right-hand side object. |
std::string wwa::json_rpc::dispatcher::parse_and_process_request | ( | const std::string & | request, |
const nlohmann::json & | extra = nlohmann::json::object() ) |
Parses and processes a JSON RPC request.
request | The JSON RPC request as a string. |
extra | Optional data that can be passed to the handler function (only for handlers added with add_ex()). |
"" | If the request is a Notification, the method returns an empty string. |
This method performs the following steps:
process_request()
method. If the request cannot be parsed, the method returns a JSON RPC error response with code -32700 (exception::PARSE_ERROR).
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.Definition at line 21 of file dispatcher.cpp.
std::string wwa::json_rpc::dispatcher::process_request | ( | const nlohmann::json & | request, |
const nlohmann::json & | extra = nlohmann::json::object() ) |
Processes a JSON RPC request.
request | The JSON RPC request as a nlohmann::json object. |
extra | Optional data that can be passed to the handler function (only for handlers added with add_ex()). |
"" | If the request is a Notification, the method returns an empty string. |
This method performs the following steps:
If the request cannot be parsed, the method returns a JSON RPC error response with code -32700
(exception::PARSE_ERROR).
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.If extra is an object, all extra fields from the JSON RPC request will be passed in the extra
property of extra. For example, given this request:
and extra
set to {"ip": "1.2.3.4"}
, the extra
parameter passed to the handler will be:
Definition at line 40 of file dispatcher.cpp.
|
friend |
Definition at line 79 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 413 of file dispatcher.h.