v6.2.0
Major networking and RPC enhancements, including JSON RPC 2.0 registry support, zero-copy REPE handling, and a standardized ABI-stable plugin interface for REPE.
Breaking Changes
-
Move
append_arraysanderror_on_const_readoptions out ofglz::optsby @stephenberry in #2110- These options are now inheritable options that must be added to a custom options struct.
- See How to Use Inheritable Options
-
WebSocket Client:
ctx_changed tocontext()method by @stephenberry in #2106// Before (won't compile) client.ctx_->stop(); // After client.context()->stop();
Highlights
JSON RPC 2.0 Registry Support
Added support for JSON RPC 2.0 protocol to the registry, enabling standard JSON-based remote procedure calls alongside REPE.
struct my_api
{
int counter = 0;
std::string greet() { return "Hello, World!"; }
int add(int value) { counter += value; return counter; }
};
// Create a JSON-RPC registry
glz::registry<glz::opts{}, glz::JSONRPC> server{};
my_api api{};
server.on(api);
// Call a function
auto response = server.call(R"({"jsonrpc":"2.0","method":"greet","id":1})");
// Returns: {"jsonrpc":"2.0","result":"Hello, World!","id":1}
// Read a variable
response = server.call(R"({"jsonrpc":"2.0","method":"counter","id":2})");
// Returns: {"jsonrpc":"2.0","result":0,"id":2}
// Call a function with parameters
response = server.call(R"({"jsonrpc":"2.0","method":"add","params":10,"id":3})");
// Returns: {"jsonrpc":"2.0","result":10,"id":3}REPE Plugin Interface
A new standardized plugin interface for REPE enables ABI-stable dynamic plugin systems that work seamlessly with glz::registry and glz::asio_server. This includes:
- Pure C header (
plugin.h) for cross-compiler compatibility - C++ helper (
plugin_helper.hpp) for implementing plugins usingglz::registry - Interface versioning for safe plugin loading
extern "C" {
uint32_t repe_plugin_interface_version() { return REPE_PLUGIN_INTERFACE_VERSION; }
const char* repe_plugin_name() { return "calculator"; }
repe_buffer repe_plugin_call(const char* request, uint64_t request_size) {
return glz::repe::plugin_call(registry, request, request_size);
}
}Zero-Copy REPE Handling
True zero-copy implementation for the REPE RPC protocol, eliminating unnecessary memory allocations and copies in the hot path:
parse_requestreturns views into the original bufferresponse_builderwrites directly to output buffer
server.call = [](std::span<const char> request, std::string& response_buffer) {
auto result = glz::repe::parse_request(request);
// req.query and req.body are views into request
registry.call(request, response_buffer); // Zero-copy
};Indexed rename_key API
A new indexed rename_key API allows transforming JSON keys based on member type information at compile time. This is useful for automatically using enum type names as JSON keys:
template <>
struct glz::meta<AppContext> {
template <size_t Index>
static constexpr auto rename_key() {
using MemberType = glz::member_type_t<AppContext, Index>;
if constexpr (std::is_enum_v<MemberType>) {
return glz::name_v<MemberType>;
} else {
return glz::member_nameof<Index, AppContext>;
}
}
};Output: {"num":42,"MyEnum":"Second","MyFlag":"Yes"}
New Compile Time Options
skip_null_members_on_read- Skip null values when reading, preserving existing values by @stephenberry in #2086skip_self_constraint- Disable self constraint validation via a compile time option by @stephenberry in #2121
Improvements
- asio_server custom call handler for routing and middleware by @stephenberry in #2096
glz::mergesupport for the registry by @stephenberry in #2088- REPE buffer helpers by @stephenberry in #2095
- Simplify REPE plugin initialization by @stephenberry in #2119
- CMake improvements by @stephenberry in #2112
- Use
weak_ptrrather thanshared_ptrfor server lifetime safety by @stephenberry in #2113 - Extract
decode_index_unknown_keyby @stephenberry in #2111 std::spanserialization tests by @stephenberry in #2109- Better client socket connection handling by @stephenberry in #2105
- Safer
unique_socket, delete copy constructor and assignment by @stephenberry in #2104 - Improve asio client
connected()status by @stephenberry in #2103 repe_plugin_datastruct by @stephenberry in #2099
Fixes
- WebSocket Client: Fix shared context and improve lifetime safety by @stephenberry in #2106
- Fix concurrent WebSocket connections (thread-safe write queue, RFC 6455 close handshake) by @stephenberry in #2092
- Fix MSVC with
std::uniform_int_distribution<unsigned int>by @stephenberry in #2085 - Fix GCC warnings in tests by @stephenberry in #2094
- Fix Clang build warnings for unit tests and bump asio dependency versions by @stephenberry in #2107
- Don't export
-Wno-missing-bracesfor languages other than C and C++ by @stephenberry in #2076 - Cleanup broken tests by @stephenberry in #2118
Testing
- Test
error_on_missing_keyswith JSON schema generation by @stephenberry in #2093 - More registry tests by @stephenberry in #2087
Documentation
Extensive documentation added:
- ASIO Setup Guide
- REPE Plugin Interface
- REPE Buffer API
- JSON-RPC Registry
- Rename Keys
- Compile Time Options
- WebSocket client documentation updates
Full Changelog: v6.1.0...v6.2.0