1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
# REPE to JSON-RPC Conversion
Utilities to convert between REPE messages with JSON bodies and JSON-RPC 2.0 messages, enabling interoperability between the REPE and JSON-RPC protocols.
## Quick Start
```cpp
#include "glaze/rpc/repe/repe_to_jsonrpc.hpp"
// REPE → JSON-RPC
repe::message msg{};
msg.query = "/add";
msg.body = R"([1,2,3])";
msg.header.id = 42;
msg.header.body_format = repe::body_format::JSON;
std::string jsonrpc = repe::to_jsonrpc_request(msg);
// {"jsonrpc":"2.0","method":"add","params":[1,2,3],"id":42}
```
## API Reference
### Converting REPE to JSON-RPC
#### Request Conversion
**Function:** `std::string to_jsonrpc_request(const message& msg)`
Converts a REPE request message to a JSON-RPC request string.
```cpp
#include "glaze/rpc/repe/repe_to_jsonrpc.hpp"
repe::message msg{};
msg.query = "/add"; // Method name (with or without leading slash)
msg.body = R"([1,2,3])"; // JSON parameters
msg.header.id = 42; // Request ID
msg.header.body_format = repe::body_format::JSON; // Must be JSON format
msg.header.notify = false; // false for request, true for notification
std::string jsonrpc_request = repe::to_jsonrpc_request(msg);
// Result: {"jsonrpc":"2.0","method":"add","params":[1,2,3],"id":42}
```
#### Response Conversion
**Function:** `std::string to_jsonrpc_response(const message& msg)`
Converts a REPE response message to a JSON-RPC response string.
```cpp
// Success response
repe::message success_msg{};
success_msg.body = R"({"result":"success"})";
success_msg.header.id = 42;
success_msg.header.body_format = repe::body_format::JSON;
success_msg.header.ec = glz::error_code::none;
std::string jsonrpc_response = repe::to_jsonrpc_response(success_msg);
// Result: {"jsonrpc":"2.0","result":{"result":"success"},"id":42}
// Error response
repe::message error_msg{};
error_msg.body = "Method not found";
error_msg.header.id = 42;
error_msg.header.body_format = repe::body_format::UTF8;
error_msg.header.ec = glz::error_code::method_not_found;
std::string jsonrpc_error = repe::to_jsonrpc_response(error_msg);
// Result: {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found","data":"Method not found"},"id":42}
```
### Converting JSON-RPC to REPE
#### Request Conversion
**Function:** `expected<message, std::string> from_jsonrpc_request(std::string_view json_request)`
Converts a JSON-RPC request string to a REPE message.
```cpp
std::string jsonrpc = R"({"jsonrpc":"2.0","method":"add","params":[1,2,3],"id":42})";
auto msg = repe::from_jsonrpc_request(jsonrpc);
if (msg.has_value()) {
// msg->query == "/add"
// msg->body == "[1,2,3]"
// msg->header.id == 42
// msg->header.body_format == repe::body_format::JSON
}
```
#### Response Conversion
**Function:** `expected<message, std::string> from_jsonrpc_response(std::string_view json_response)`
Converts a JSON-RPC response string to a REPE message.
```cpp
// Success response
std::string jsonrpc_success = R"({"jsonrpc":"2.0","result":{"value":42},"id":10})";
auto success = repe::from_jsonrpc_response(jsonrpc_success);
if (success.has_value()) {
// success->header.id == 10
// success->header.ec == glz::error_code::none
// success->body contains {"value":42}
}
// Error response
std::string jsonrpc_error = R"({"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found","data":"Details"},"id":42})";
auto error = repe::from_jsonrpc_response(jsonrpc_error);
if (error.has_value()) {
// error->header.id == 42
// error->header.ec == glz::error_code::method_not_found
// error->body == "Details"
}
```
### Error Code Mapping
| REPE Error | JSON-RPC Error | Code |
|------------|----------------|------|
| `error_code::none` | `error_e::no_error` | 0 |
| `error_code::parse_error` | `error_e::parse_error` | -32700 |
| `error_code::syntax_error` | `error_e::parse_error` | -32700 |
| `error_code::invalid_header` | `error_e::invalid_request` | -32600 |
| `error_code::version_mismatch` | `error_e::invalid_request` | -32600 |
| `error_code::method_not_found` | `error_e::method_not_found` | -32601 |
| Other errors | `error_e::internal` | -32603 |
### Notifications
REPE notifications (messages with `notify = true`) are converted to JSON-RPC notifications (requests with `id = null`):
```cpp
repe::message notification{};
notification.query = "/notify";
notification.body = R"({"message":"hello"})";
notification.header.notify = true;
std::string jsonrpc = repe::to_jsonrpc_request(notification);
// Result: {"jsonrpc":"2.0","method":"notify","params":{"message":"hello"},"id":null}
```
### ID Handling
REPE uses `uint64_t` for IDs, while JSON-RPC supports strings, numbers, or null:
- Numeric IDs are directly mapped between protocols
- Numeric strings (e.g., `"123"`) are parsed as numbers
- Non-numeric strings are hashed to create a REPE ID
```cpp
// Numeric string ID
std::string jsonrpc = R"({"jsonrpc":"2.0","method":"test","params":[],"id":"999"})";
auto msg = repe::from_jsonrpc_request(jsonrpc);
// msg->header.id == 999
// Non-numeric string ID
std::string jsonrpc2 = R"({"jsonrpc":"2.0","method":"test","params":[],"id":"test-123"})";
auto msg2 = repe::from_jsonrpc_request(jsonrpc2);
// msg2->header.id == hash("test-123")
```
### Requirements
- REPE message body must be in JSON format for conversion to JSON-RPC requests
- REPE message body should be in JSON or UTF8 format for conversion to JSON-RPC responses
- The query field in REPE requests is treated as the method name (leading slash is optional)
### Bridging Protocols Example
```cpp
#include "glaze/rpc/repe/repe_to_jsonrpc.hpp"
// Receive JSON-RPC request from client
std::string jsonrpc_request = R"({"jsonrpc":"2.0","method":"add","params":[1,2,3],"id":42})";
// Convert to REPE
auto repe_request = repe::from_jsonrpc_request(jsonrpc_request);
if (repe_request.has_value()) {
// Process with REPE server
repe::message repe_response = process(repe_request.value());
// Convert response back to JSON-RPC
std::string jsonrpc_response = repe::to_jsonrpc_response(repe_response);
}
```
|