JSON RPC
JSON-RPC 2.0 library for C++
request.cpp
Go to the documentation of this file.
1#include "request.h"
2#include "exception.h"
3#include "utils.h"
4
5/**
6 * @file request.cpp
7 * @brief Implements the functionality for handling JSON RPC requests.
8 *
9 * This source file contains the implementation of the `jsonrpc_request` struct's methods.
10 * It includes the deserialization of a JSON object into a `jsonrpc_request` structure and the validation of the JSON RPC request.
11 *
12 * The file uses the nlohmann::json library for JSON handling and includes additional headers for exception handling and utility functions.
13 *
14 * @see https://www.jsonrpc.org/specification#request_object
15 * @internal
16 */
17
18namespace wwa::json_rpc {
19
20/**
21 * @brief Deserializes a JSON object into a `jsonrpc_request` structure.
22 * @internal
23 *
24 * @param j The JSON object to deserialize.
25 * @param r The `jsonrpc_request` structure to populate.
26 *
27 * @details This function deserializes a JSON object into a `jsonrpc_request` structure.
28 * * It extracts the `jsonrpc` version, `method` name, `params`, and `id` from the JSON object.
29 * * If the `params` field is not present, it defaults to an empty array.
30 * * If the `params` field is an object, it is wrapped in an array.
31 *
32 * @note This function cannot be moved to an anonymous namespace because of Argument-Dependent Lookup (ADL).
33 *
34 * @see https://www.jsonrpc.org/specification#request_object
35 * @see https://github.com/nlohmann/json?tab=readme-ov-file#arbitrary-types-conversions
36 */
37// NOLINTNEXTLINE(misc-use-anonymous-namespace) -- cannot move to an anonymous namespace because of ADL
38static void from_json(const nlohmann::json& j, jsonrpc_request& r)
39{
40 r.params = nlohmann::json(nlohmann::json::value_t::discarded);
41 r.id = nlohmann::json(nlohmann::json::value_t::discarded);
42
43 j.at("jsonrpc").get_to(r.jsonrpc);
44 j.at("method").get_to(r.method);
45
46 if (j.contains("params")) {
47 r.params = j["params"];
48 }
49
50 if (j.contains("id")) {
51 r.id = j["id"];
52 }
53
54 if (r.params.is_discarded()) {
55 r.params = nlohmann::json::array();
56 }
57 else if (r.params.is_object()) {
58 r.params = nlohmann::json::array({r.params});
59 }
60}
61
62jsonrpc_request jsonrpc_request::from_json(const nlohmann::json& request)
63{
65 try {
66 request.get_to(req);
67 }
68 catch (const nlohmann::json::exception&) {
69 throw exception(exception::INVALID_REQUEST, err_bad_request);
70 }
71
72 if (req.jsonrpc != "2.0") {
73 throw json_rpc::exception(json_rpc::exception::INVALID_REQUEST, json_rpc::err_not_jsonrpc_2_0_request);
74 }
75
76 if (!req.params.is_array()) {
77 throw json_rpc::exception(json_rpc::exception::INVALID_PARAMS, json_rpc::err_bad_params_type);
78 }
79
80 if (req.method.empty()) {
81 throw json_rpc::exception(json_rpc::exception::INVALID_REQUEST, json_rpc::err_empty_method);
82 }
83
84 if (!is_valid_request_id(req.id)) {
85 throw json_rpc::exception(json_rpc::exception::INVALID_REQUEST, json_rpc::err_bad_id_type);
86 }
87
88 req.extra = request;
89 req.extra.erase("jsonrpc");
90 req.extra.erase("method");
91 req.extra.erase("params");
92 req.extra.erase("id");
93 return req;
94}
95
96} // namespace wwa::json_rpc
JSON RPC Exception class.
Definition exception.h:86
static constexpr int INVALID_PARAMS
Invalid method parameter(s).
Definition exception.h:115
static constexpr int INVALID_REQUEST
The JSON sent is not a valid Request object.
Definition exception.h:105
static void from_json(const nlohmann::json &j, jsonrpc_request &r)
Deserializes a JSON object into a jsonrpc_request structure.
Definition request.cpp:38
Represents a JSON RPC request.
Definition request.h:22