JSON RPC
JSON-RPC 2.0 library for C++
dispatcher_p.h
Go to the documentation of this file.
1#ifndef FB656817_7041_48D5_80B2_347168163158
2#define FB656817_7041_48D5_80B2_347168163158
3
4/**
5 * @file
6 * @brief Contains the private implementation details of the JSON RPC dispatcher class.
7 * @internal
8 */
9
10#include <functional>
11#include <string>
12#include <string_view>
13#include <unordered_map>
14#include "dispatcher.h"
15
16namespace wwa::json_rpc {
17
18class exception;
19
20/**
21 * @brief Custom hasher for `std::string_view`.
22 * @internal
23 *
24 * This struct provides a custom hash function for `std::string_view` to be used in unordered containers.
25 */
26struct hasher {
27 using is_transparent = void; ///< Indicates that the hasher supports transparent key lookup.
28
29 /**
30 * @brief Computes the hash value for a given `std::string_view`.
31 *
32 * @param s The `std::string_view` to hash.
33 * @return The hash value.
34 */
35 std::size_t operator()(std::string_view s) const noexcept
36 {
37 const std::hash<std::string_view> h;
38 return h(s);
39 }
40};
41
42/**
43 * @brief Represents a JSON RPC request.
44 * @internal
45 *
46 * This struct holds the components of a JSON RPC request, including the JSON RPC version, method name, parameters, and ID.
47 *
48 * @see https://www.jsonrpc.org/specification#request_object
49 */
51 std::string jsonrpc; ///< The JSON RPC version.
52 std::string method; ///< The name of the method to be invoked.
53 nlohmann::json params; ///< The parameters for the method.
54 nlohmann::json id; ///< The ID of the request.
55};
56
57/**
58 * @brief Private implementation of the JSON RPC dispatcher class.
59 * @internal
60 *
61 * This class contains the private members and methods used by the `dispatcher` class to manage method handlers and process requests.
62 */
64public:
65 /**
66 * @brief Constructs a new `dispatcher_private` object.
67 *
68 * @param q Pointer to the public `dispatcher` object.
69 */
70 explicit dispatcher_private(dispatcher* q) : q_ptr(q) {}
71
72 /**
73 * @brief Adds a method handler.
74 *
75 * @param method The name of the method.
76 * @param handler The handler function.
77 *
78 * @details This method registers a handler function for a given method name.
79 * The handler function will be invoked when a request for the specified method is received.
80 */
81 void add_handler(std::string&& method, dispatcher::handler_t&& handler);
82
83 /**
84 * @brief Processes a JSON RPC request.
85 *
86 * @param request The JSON RPC request as a `nlohmann::json` object.
87 * @param extra The extra parameter to pass to the method handlers.
88 * @return The response serialized into a JSON object.
89 *
90 * @details This method parses the JSON RPC request, validates it, and invokes the appropriate method handler.
91 *
92 * @see dispatcher::process_request()
93 */
95
96 /**
97 * @brief Generates an error response.
98 *
99 * @param e The exception containing the error details.
100 * @param id The ID of the request.
101 * @return The error response serialized into a JSON object.
102 *
103 * @details This method creates a JSON RPC error response based on the provided exception and request ID.
104 * @see exception::to_json()
105 */
107
108private:
109 dispatcher* q_ptr; ///< Pointer to the public `dispatcher` object.
110 /** @brief Map of method names to handler functions. */
112
113 /**
114 * @brief Parses a JSON RPC request.
115 *
116 * @param request The JSON RPC request as a `nlohmann::json` object.
117 * @param extra Extra fields extracted from @a request
118 * @return The parsed JSON RPC request.
119 *
120 * @details This method extracts the components of a JSON RPC request from the provided JSON object.
121 */
122 static jsonrpc_request parse_request(const nlohmann::json& request, nlohmann::json& extra);
123
124 /**
125 * @brief Processes a batch request.
126 *
127 * @param request The batch request as a `nlohmann::json` array.
128 * @param extra The extra parameter to pass to the method handlers.
129 * @return The response serialized into a JSON array.
130 *
131 * @details This method processes a batch request by invoking the method handlers for each request in the batch.
132 *
133 * @see dispatcher::process_request()
134 */
136
137 /**
138 * @brief Validates a JSON RPC request.
139 *
140 * @param r The JSON RPC request to validate.
141 *
142 * @details This method checks the validity of the JSON RPC request, ensuring that all required fields are present and correctly formatted.
143 * @throws exception If the request is invalid.
144 * @see exception::INVALID_REQUEST, exception::INVALID_PARAMS
145 */
146 static void validate_request(const jsonrpc_request& r);
147
148 /**
149 * @brief Invokes a method handler.
150 *
151 * @param method The name of the method to invoke.
152 * @param params The parameters for the method.
153 * @param extra The extra parameter to pass to the method handlers.
154 * @return The result of the method invocation serialized into a JSON object.
155 *
156 * @details This method finds the handler for the specified method and invokes it with the provided parameters.
157 * @throws exception If the method is not found or the invocation fails.
158 * @see exception::METHOD_NOT_FOUND
159 */
161};
162
163} // namespace wwa::json_rpc
164
165#endif /* FB656817_7041_48D5_80B2_347168163158 */
Private implementation of the JSON RPC dispatcher class.
static jsonrpc_request parse_request(const nlohmann::json &request, nlohmann::json &extra)
Parses a JSON RPC request.
nlohmann::json invoke(const std::string &method, const nlohmann::json &params, const nlohmann::json &extra)
Invokes a method handler.
static nlohmann::json generate_error_response(const exception &e, const nlohmann::json &id)
Generates an error response.
nlohmann::json process_batch_request(const nlohmann::json &request, const nlohmann::json &extra)
Processes a batch request.
static void validate_request(const jsonrpc_request &r)
Validates a JSON RPC request.
dispatcher * q_ptr
Pointer to the public dispatcher object.
dispatcher_private(dispatcher *q)
Constructs a new dispatcher_private object.
void add_handler(std::string &&method, dispatcher::handler_t &&handler)
Adds a method handler.
nlohmann::json process_request(const nlohmann::json &request, const nlohmann::json &extra)
Processes a JSON RPC request.
A class that manages JSON RPC method handlers and processes JSON RPC requests.
Definition dispatcher.h:77
dispatcher & operator=(dispatcher &&rhs)=default
Move assignment operator.
dispatcher(dispatcher &&rhs)=default
Move constructor.
virtual void on_request(const nlohmann::json &extra)
Invoked when a request is received.
void add_ex(std::string_view method, F &&f, C instance)
Adds a method handler with an extra parameter and a class instance.
Definition dispatcher.h:277
std::string parse_and_process_request(const std::string &request, const nlohmann::json &extra=nlohmann::json::object())
Parses and processes a JSON RPC request.
constexpr auto create_closure(C inst, F &&f) const
Creates a closure for invoking a member function with JSON parameters.
Definition dispatcher.h:455
std::string process_request(const nlohmann::json &request, const nlohmann::json &extra=nlohmann::json::object())
Processes a JSON RPC request.
virtual void on_request_processed(const std::string &method, int code, const nlohmann::json &extra)
Invoked after the method handler is called.
void add_internal_method(std::string_view method, handler_t &&handler)
Adds a method handler for the specified method.
void add(std::string_view method, F &&f)
Adds a method handler f for the method method.
Definition dispatcher.h:192
virtual void on_method(const std::string &method, const nlohmann::json &extra)
Invoked right before the method handler is called.
void add(std::string_view method, F &&f, C instance)
Adds a method to the dispatcher with the specified instance and function.
Definition dispatcher.h:210
dispatcher()
Class constructor.
dispatcher(const dispatcher &)=delete
dispatcher & operator=(const dispatcher &)=delete
virtual ~dispatcher()
Class destructor.
void add_ex(std::string_view method, F &&f)
Adds a method handler with an extra parameter.
Definition dispatcher.h:254
std::unique_ptr< dispatcher_private > d_ptr
Pointer to the implementation (Pimpl idiom).
Definition dispatcher.h:413
JSON RPC Exception class.
Definition exception.h:79
exception(const exception &)=default
Default copy constructor.
~exception() override
Default destructor.
nlohmann::json m_data
Custom data associated with the error.
Definition exception.h:224
std::string m_message
Error message.
Definition exception.h:223
int code() const noexcept
Returns the error code.
Definition exception.h:176
const std::string & message() const noexcept
Returns the error message.
Definition exception.h:183
exception(exception &&)=default
Default move constructor.
exception(int code, std::string_view message)
Construct a new exception object.
Definition exception.h:138
exception & operator=(const exception &rhs)=default
Default copy assignment operator.
const nlohmann::json & data() const noexcept
Returns custom data associated with the error.
Definition exception.h:190
exception & operator=(exception &&rhs)=default
Default move assignment operator.
const char * what() const noexcept override
Returns the error message.
Definition exception.h:200
nlohmann::json to_json() const
Returns the error message as an Error Object.
Definition exception.h:208
exception(int code, std::string_view message, const T &data)
Construct a new exception object with additional data.
Definition exception.h:127
int m_code
Error code.
Definition exception.h:225
#define WWA_JSONRPC_EXPORT
Macro for exporting symbols when building the library dynamically or importing symbols when using the...
Definition export.h:42
static constexpr int INVALID_PARAMS
Invalid method parameter(s).
Definition exception.h:108
static constexpr int INTERNAL_ERROR
Internal JSON-RPC error.
Definition exception.h:113
static constexpr int METHOD_NOT_FOUND
The method does not exist or is not available.
Definition exception.h:103
static constexpr int INVALID_REQUEST
The JSON sent is not a valid Request object.
Definition exception.h:98
static constexpr int PARSE_ERROR
Invalid JSON was received by the server.
Definition exception.h:93
static constexpr std::string_view err_method_not_found
Error message for when the method is not found.
Definition exception.h:43
static constexpr std::string_view err_not_jsonrpc_2_0_request
Error message for when the request is not a JSON-RPC 2.0 request.
Definition exception.h:31
static constexpr std::string_view err_empty_batch
Error message for when the batch request is empty.
Definition exception.h:70
static constexpr std::string_view err_empty_method
Error message for when the method is empty.
Definition exception.h:49
static constexpr std::string_view err_bad_params_type
Error message for when the parameters are not an array or an object.
Definition exception.h:55
static constexpr std::string_view err_invalid_params_passed_to_method
Error message for when the parameters passed to the method are not correct.
Definition exception.h:37
static constexpr std::string_view err_bad_id_type
Error message for when the ID is not a number, a string, or null.
Definition exception.h:63
constexpr auto convert_args(const nlohmann::json &params, std::index_sequence< Indices... >)
Converts JSON parameters to a tuple of arguments based on the specified types.
Definition details.h:346
constexpr auto make_inst_tuple(C inst)
Creates a tuple containing the instance if it is a class pointer, or an empty tuple if it is a null p...
Definition details.h:239
Contains the implementation details of the JSON RPC library.
Definition details.h:31
Primary template for function traits.
Definition details.h:172
Custom hasher for std::string_view.
std::size_t operator()(std::string_view s) const noexcept
Computes the hash value for a given std::string_view.
Represents a JSON RPC request.
std::string method
The name of the method to be invoked.
std::string jsonrpc
The JSON RPC version.
nlohmann::json id
The ID of the request.
nlohmann::json params
The parameters for the method.