JSON RPC
JSON-RPC 2.0 library for C++
wwa::json_rpc::dispatcher_private Class Reference

Private implementation of the JSON RPC dispatcher class. More...

#include <dispatcher_p.h>

+ Collaboration diagram for wwa::json_rpc::dispatcher_private:

Public Member Functions

 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.
 

Static Public Member Functions

static nlohmann::json generate_error_response (const exception &e, const nlohmann::json &id)
 Generates an error response.
 

Private Member Functions

nlohmann::json invoke (const std::string &method, const nlohmann::json &params, const nlohmann::json &extra)
 Invokes a method handler.
 
nlohmann::json process_batch_request (const nlohmann::json &request, const nlohmann::json &extra)
 Processes a batch request.
 

Static Private Member Functions

static jsonrpc_request parse_request (const nlohmann::json &request, nlohmann::json &extra)
 Parses a JSON RPC request.
 
static void validate_request (const jsonrpc_request &r)
 Validates a JSON RPC request.
 

Private Attributes

std::unordered_map< std::string, dispatcher::handler_t, hasher, std::equal_to<> > m_methods
 Map of method names to handler functions.
 
dispatcherq_ptr
 Pointer to the public dispatcher object.
 

Detailed Description

Private implementation of the JSON RPC dispatcher class.

This class contains the private members and methods used by the dispatcher class to manage method handlers and process requests.

Definition at line 63 of file dispatcher_p.h.

Constructor & Destructor Documentation

◆ dispatcher_private()

wwa::json_rpc::dispatcher_private::dispatcher_private ( dispatcher * q)
inlineexplicit

Constructs a new dispatcher_private object.

Parameters
qPointer to the public dispatcher object.

Definition at line 70 of file dispatcher_p.h.

70: q_ptr(q) {}
dispatcher * q_ptr
Pointer to the public dispatcher object.

Member Function Documentation

◆ add_handler()

void wwa::json_rpc::dispatcher_private::add_handler ( std::string && method,
dispatcher::handler_t && handler )

Adds a method handler.

Parameters
methodThe name of the method.
handlerThe 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 80 of file dispatcher_p.cpp.

81{
82 this->m_methods.try_emplace(std::move(method), std::move(handler));
83}
std::unordered_map< std::string, dispatcher::handler_t, hasher, std::equal_to<> > m_methods
Map of method names to handler functions.

◆ generate_error_response()

nlohmann::json wwa::json_rpc::dispatcher_private::generate_error_response ( const exception & e,
const nlohmann::json & id )
static

Generates an error response.

Parameters
eThe exception containing the error details.
idThe ID of the request.
Returns
The error response serialized into a JSON object.

This method creates a JSON RPC error response based on the provided exception and request ID.

See also
exception::to_json()

Definition at line 198 of file dispatcher_p.cpp.

199{
200 return nlohmann::json({{"jsonrpc", "2.0"}, {"error", e.to_json()}, {"id", id}});
201}

◆ invoke()

nlohmann::json wwa::json_rpc::dispatcher_private::invoke ( const std::string & method,
const nlohmann::json & params,
const nlohmann::json & extra )
private

Invokes a method handler.

Parameters
methodThe name of the method to invoke.
paramsThe parameters for the method.
extraThe extra parameter to pass to the method handlers.
Returns
The result of the method invocation serialized into a JSON object.

This method finds the handler for the specified method and invokes it with the provided parameters.

Exceptions
exceptionIf the method is not found or the invocation fails.
See also
exception::METHOD_NOT_FOUND

Definition at line 204 of file dispatcher_p.cpp.

205{
206 if (const auto it = this->m_methods.find(method); it != this->m_methods.end()) {
207 this->q_ptr->on_method(method, extra);
208 const auto response = it->second(extra, params);
209 this->q_ptr->on_request_processed(method, 0, extra);
210 return response;
211 }
212
214}
virtual void on_request_processed(const std::string &method, int code, const nlohmann::json &extra)
Invoked after the method handler is called.
virtual void on_method(const std::string &method, const nlohmann::json &extra)
Invoked right before the method handler is called.
static constexpr int METHOD_NOT_FOUND
The method does not exist or is not available.
Definition exception.h:103
static constexpr std::string_view err_method_not_found
Error message for when the method is not found.
Definition exception.h:43

◆ parse_request()

jsonrpc_request wwa::json_rpc::dispatcher_private::parse_request ( const nlohmann::json & request,
nlohmann::json & extra )
staticprivate

Parses a JSON RPC request.

Parameters
requestThe JSON RPC request as a nlohmann::json object.
extraExtra fields extracted from request
Returns
The parsed JSON RPC request.

This method extracts the components of a JSON RPC request from the provided JSON object.

Definition at line 85 of file dispatcher_p.cpp.

86{
87 try {
88 auto req = request.get<jsonrpc_request>();
89 extra = request;
90 extra.erase("jsonrpc");
91 extra.erase("method");
92 extra.erase("params");
93 extra.erase("id");
94 return req;
95 }
96 catch (const nlohmann::json::exception& e) {
97 throw exception(exception::INVALID_REQUEST, e.what());
98 }
99}
static constexpr int INVALID_REQUEST
The JSON sent is not a valid Request object.
Definition exception.h:98

◆ process_batch_request()

nlohmann::json wwa::json_rpc::dispatcher_private::process_batch_request ( const nlohmann::json & request,
const nlohmann::json & extra )
private

Processes a batch request.

Parameters
requestThe batch request as a nlohmann::json array.
extraThe extra parameter to pass to the method handlers.
Returns
The response serialized into a JSON array.

This method processes a batch request by invoking the method handlers for each request in the batch.

See also
dispatcher::process_request()

Definition at line 102 of file dispatcher_p.cpp.

103{
104 if (request.empty()) {
105 this->q_ptr->on_request(extra);
108 exception(exception::INVALID_REQUEST, err_empty_batch), nlohmann::json(nullptr)
109 );
110 }
111
112 auto response = nlohmann::json::array();
113 for (const auto& req : request) {
114 if (!req.is_object()) {
115 this->q_ptr->on_request(extra);
117 exception(exception::INVALID_REQUEST, err_not_jsonrpc_2_0_request), nlohmann::json(nullptr)
118 );
119
120 response.push_back(r);
122 }
123 else if (const auto res = this->process_request(req, extra); !res.is_discarded()) {
124 response.push_back(res);
125 }
126 }
127
128 return response.empty() ? nlohmann::json(nlohmann::json::value_t::discarded) : response;
129}
static nlohmann::json generate_error_response(const exception &e, const nlohmann::json &id)
Generates an error response.
nlohmann::json process_request(const nlohmann::json &request, const nlohmann::json &extra)
Processes a JSON RPC request.
virtual void on_request(const nlohmann::json &extra)
Invoked when a request is received.
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

◆ process_request()

nlohmann::json wwa::json_rpc::dispatcher_private::process_request ( const nlohmann::json & request,
const nlohmann::json & extra )

Processes a JSON RPC request.

Parameters
requestThe JSON RPC request as a nlohmann::json object.
extraThe extra parameter to pass to the method handlers.
Returns
The response serialized into a JSON object.

This method parses the JSON RPC request, validates it, and invokes the appropriate method handler.

See also
dispatcher::process_request()

Definition at line 132 of file dispatcher_p.cpp.

133{
134 if (request.is_array()) {
135 return this->process_batch_request(request, extra);
136 }
137
138 this->q_ptr->on_request(extra);
139 auto request_id = request.contains("id") ? request["id"] : nlohmann::json(nullptr);
140 if (!is_valid_request_id(request_id)) {
141 request_id = nlohmann::json(nullptr);
142 }
143
144 std::string method;
145 nlohmann::json extra_data = extra;
146 try {
147 nlohmann::json extra_fields;
148 auto req = dispatcher_private::parse_request(request, extra_fields);
150 method = req.method;
151 request_id = req.id;
152
153 if (extra.is_object() && !extra_fields.empty()) {
154 extra_data["extra"] = extra_fields;
155 }
156
157 const auto res = this->invoke(method, req.params, extra_data);
158 if (!req.id.is_discarded()) {
159 return nlohmann::json({{"jsonrpc", "2.0"}, {"result", res}, {"id", req.id}});
160 }
161
162 // NOLINTNEXTLINE(modernize-return-braced-init-list) -- braced init will create a JSON array
163 return nlohmann::json(nlohmann::json::value_t::discarded);
164 }
165 catch (const exception& e) {
166 this->q_ptr->on_request_processed(method, e.code(), extra_data);
167 return request_id.is_discarded() ? nlohmann::json(nlohmann::json::value_t::discarded)
169 }
170 catch (const std::exception& e) {
171 this->q_ptr->on_request_processed(method, exception::INTERNAL_ERROR, extra_data);
172 return request_id.is_discarded() ? nlohmann::json(nlohmann::json::value_t::discarded)
174 exception(exception::INTERNAL_ERROR, e.what()), request_id
175 );
176 }
177}
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.
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_private(dispatcher *q)
Constructs a new dispatcher_private object.
static constexpr int INTERNAL_ERROR
Internal JSON-RPC error.
Definition exception.h:113
bool is_valid_request_id(const nlohmann::json &id)
Checks if the provided JSON value is a valid JSON RPC request ID.

◆ validate_request()

void wwa::json_rpc::dispatcher_private::validate_request ( const jsonrpc_request & r)
staticprivate

Validates a JSON RPC request.

Parameters
rThe JSON RPC request to validate.

This method checks the validity of the JSON RPC request, ensuring that all required fields are present and correctly formatted.

Exceptions
exceptionIf the request is invalid.
See also
exception::INVALID_REQUEST, exception::INVALID_PARAMS

Definition at line 179 of file dispatcher_p.cpp.

180{
181 if (r.jsonrpc != "2.0") {
183 }
184
185 if (!r.params.is_array()) {
187 }
188
189 if (r.method.empty()) {
191 }
192
193 if (!is_valid_request_id(r.id)) {
195 }
196}
static constexpr int INVALID_PARAMS
Invalid method parameter(s).
Definition exception.h:108
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_bad_id_type
Error message for when the ID is not a number, a string, or null.
Definition exception.h:63

Member Data Documentation

◆ m_methods

std::unordered_map<std::string, dispatcher::handler_t, hasher, std::equal_to<> > wwa::json_rpc::dispatcher_private::m_methods
private

Map of method names to handler functions.

Definition at line 111 of file dispatcher_p.h.

◆ q_ptr

dispatcher* wwa::json_rpc::dispatcher_private::q_ptr
private

Pointer to the public dispatcher object.

Definition at line 109 of file dispatcher_p.h.


The documentation for this class was generated from the following files: