The JSON-RPC 2.0 library now supports automatic serialization and deserialization of C++ types!
detail::deserialize_params<ParamsT>()- Converts JSON params to C++ typedetail::serialize_params<ParamsT>()- Converts C++ type to JSON params (with array wrapping)detail::serialize_result<ResultT>()- Converts C++ result to JSONdetail::make_typed_handler<ParamsT, ResultT>()- Wraps typed function as JSON handlerdetail::make_no_params_handler<ResultT>()- Wraps no-params function as JSON handler
// Original method (still supported)
void add(const std::string &method, handler_t fn);
// NEW: Typed handler
template <typename ParamsT, typename ResultT>
void add_typed(const std::string &method, std::function<ResultT(ParamsT)> fn);
// NEW: No-params handler
template <typename ResultT>
void add_no_params(const std::string &method, std::function<ResultT()> fn);// Server-side: NEW typed methods
template <typename ParamsT, typename ResultT>
void add_typed(const std::string &method, std::function<ResultT(ParamsT)> fn);
template <typename ResultT>
void add_no_params(const std::string &method, std::function<ResultT()> fn);
// Client-side: NEW typed request methods
template <typename ParamsT, typename ResultT>
std::string send_request_typed(
const std::string &method,
const ParamsT ¶ms,
std::function<void(ResultT)> on_result,
error_cb on_error = nullptr
);
template <typename ParamsT>
void send_notification_typed(const std::string &method, const ParamsT ¶ms);Created tests/test_serialization.cpp with 12 passing tests:
- ✓ Basic types (int → int)
- ✓ String types (string → string)
- ✓ Custom struct (Point → Point)
- ✓ Complex struct (Person → Person)
- ✓ Void return type (int → void)
- ✓ No parameters (void → int)
- ✓ Vector types (vector → vector)
- ✓ Error handling with typed params
- ✓ Invalid params detection
- ✓ Endpoint with typed methods
- ✓ Endpoint typed client request
- ✓ Mix raw JSON and typed methods
Created docs/SERIALIZATION.md with:
- Overview and benefits
- Basic usage examples
- Custom struct serialization
- STL container support
- Error handling
- JSON-RPC 2.0 compliance details
- Client-side typed requests
- Complete working example
- API reference
- Migration guide
// Compile-time type checking
disp.add_typed<int, int>("double", [](int x) {
return x * 2;
});struct Point { double x, y; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Point, x, y)
disp.add_typed<Point, Point>("move", [](Point p) {
p.x += 10; p.y += 20;
return p;
});- Invalid params →
-32602error - JSON conversion errors caught automatically
- Detailed error messages with
datafield
- Single parameters wrapped in arrays:
[5] - Struct parameters as objects:
[{"a": 1, "b": 2}] - Array parameters passed as-is
- All existing raw JSON handlers still work
- Can mix typed and raw JSON handlers
- Zero breaking changes
JSON-RPC 2.0 spec requires params to be array or object. We wrap single primitive values in arrays for compliance:
// Request with typed int parameter
{
"jsonrpc": "2.0",
"method": "double",
"params": [5], // <-- wrapped in array
"id": 1
}All template functions resolve at compile time - zero runtime overhead.
- JSON conversion errors →
invalid_params(-32602) - User exceptions →
internal_error(-32603) rpc_exception→ custom error codes
include/jsonrpc.hpp- Added 200+ lines of serialization supporttests/test_serialization.cpp- 342 lines of comprehensive testsdocs/SERIALIZATION.md- 450+ lines of documentationsrc/main.cpp- Addedrun_serialization_tests()call
=== JSON-RPC 2.0 Serialization/Deserialization Tests ===
Test 1: Basic types (int -> int)
✓ Passed
Test 2: String types (string -> string)
✓ Passed
Test 3: Custom struct (Point -> Point)
✓ Passed
Test 4: Complex struct (Person -> Person)
✓ Passed
Test 5: Void return type (int -> void)
✓ Passed
Test 6: No parameters (void -> int)
✓ Passed
Test 7: Vector types (vector<int> -> vector<int>)
✓ Passed
Test 8: Error handling with typed params
✓ Passed
Test 9: Invalid params detection
✓ Passed
Test 10: Endpoint with typed methods
✓ Passed
Test 11: Endpoint typed client request
✓ Passed
Test 12: Mix raw JSON and typed methods
✓ Passed
=== All serialization tests passed! ===
This feature was implemented in response to community feedback from r/cpp:
"It would be nice to make use of json serialisation / deserialization to have methods take and return data types rather than json objects" — u/jonathanhiggs
Status: ✅ Implemented, tested, and documented!
- ✅ All tests passing
- 📝 Commit changes to git
- 🚀 Push to GitHub
- 📢 Update Medium article
- 💬 Reply to Reddit comment with implementation details
-
Lines added: ~750 lines
- jsonrpc.hpp: ~200 lines
- test_serialization.cpp: ~342 lines
- SERIALIZATION.md: ~450 lines
- main.cpp: ~5 lines
-
Tests: 12 new tests (100% pass rate)
-
Build time: No noticeable increase
-
Runtime overhead: Zero (template resolution at compile time)
- Less Boilerplate: No more manual
.get<T>()calls - Type Safety: Compile-time checking
- Better DX: More intuitive API
- Flexibility: Works with any serializable type
- Compatibility: Doesn't break existing code
Implementation Time: ~2 hours
Status: ✅ Complete and Production Ready
Breaking Changes: None
Backward Compatibility: 100%