Partial Write¶
Glaze supports partial object writing, allowing you to serialize only specific fields. There are three approaches:
- Compile-time partial write - Uses JSON pointers as template parameters (zero runtime overhead)
- Runtime partial write (whitelist) - Specify keys to include at runtime
- Runtime exclude write (blacklist) - Specify keys to exclude at runtime
Compile-Time Partial Write¶
Use glz::json_ptrs to specify JSON pointer paths at compile time. This approach supports nested paths and has zero runtime overhead.
struct animals_t
{
std::string lion = "Lion";
std::string tiger = "Tiger";
std::string panda = "Panda";
struct glaze
{
using T = animals_t;
static constexpr auto value = glz::object(&T::lion, &T::tiger, &T::panda);
};
};
struct zoo_t
{
animals_t animals{};
std::string name{"My Awesome Zoo"};
struct glaze
{
using T = zoo_t;
static constexpr auto value = glz::object(&T::animals, &T::name);
};
};
"partial write"_test = [] {
static constexpr auto partial = glz::json_ptrs("/name", "/animals/tiger");
zoo_t obj{};
std::string s{};
const auto ec = glz::write_json<partial>(obj, s);
expect(!ec);
expect(s == R"({"animals":{"tiger":"Tiger"},"name":"My Awesome Zoo"})") << s;
};
Runtime Partial Write¶
Use glz::write_json_partial to specify keys dynamically at runtime. This is useful when the set of keys to serialize is determined at runtime (e.g., based on user input, configuration, or message type).
Basic Usage¶
struct my_struct
{
int x = 10;
std::string name = "example";
double value = 3.14;
bool active = true;
};
my_struct obj{};
std::string buffer;
// Specify keys at runtime
std::vector<std::string> keys = {"name", "x"};
auto ec = glz::write_json_partial(obj, keys, buffer);
// Result: {"name":"example","x":10}
Key Order¶
The output key order matches the order of keys in your input container:
std::vector<std::string_view> keys = {"value", "name", "x"};
glz::write_json_partial(obj, keys, buffer);
// Result: {"value":3.14,"name":"example","x":10}
Supported Key Containers¶
Any range of string-like types works:
// std::vector<std::string>
std::vector<std::string> keys1 = {"x", "name"};
// std::vector<std::string_view>
std::vector<std::string_view> keys2 = {"x", "name"};
// std::array
std::array<std::string_view, 2> keys3 = {"x", "name"};
Error Handling¶
If a key doesn't exist in the struct, error_code::unknown_key is returned:
std::vector<std::string> keys = {"x", "nonexistent"};
auto ec = glz::write_json_partial(obj, keys, buffer);
if (ec.ec == glz::error_code::unknown_key) {
// Handle unknown key error
}
Empty Keys¶
An empty key container produces an empty JSON object:
Duplicate Keys¶
Duplicate keys are allowed and will write the field multiple times:
std::vector<std::string> keys = {"x", "x"};
glz::write_json_partial(obj, keys, buffer);
// Result: {"x":10,"x":10}
Options Support¶
Runtime partial write supports standard Glaze options like prettify:
std::vector<std::string> keys = {"x", "name"};
glz::write_json_partial<glz::opts{.prettify = true}>(obj, keys, buffer);
// Result:
// {
// "x": 10,
// "name": "example"
// }
Return Types¶
Three overloads are available:
// 1. Write to resizable buffer (std::string, std::vector<char>)
error_ctx write_json_partial(T&& value, const Keys& keys, Buffer&& buffer);
// 2. Write to raw buffer (char*)
expected<size_t, error_ctx> write_json_partial(T&& value, const Keys& keys, Buffer&& buffer);
// 3. Return a new string
expected<std::string, error_ctx> write_json_partial(T&& value, const Keys& keys);
Works with Reflectable Types¶
Runtime partial write works with both explicit Glaze metadata and pure reflection (C++ aggregates):
// No glz::meta needed - pure reflection
struct reflectable_struct
{
int field1 = 100;
std::string field2 = "test";
};
reflectable_struct obj{};
std::vector<std::string> keys = {"field2"};
glz::write_json_partial(obj, keys, buffer);
// Result: {"field2":"test"}
Runtime Exclude Write (Blacklist)¶
Use glz::write_json_exclude to specify keys to exclude at runtime. This is useful when you want to serialize most fields but omit a few (e.g., sensitive data like passwords, internal IDs, or deprecated fields).
Basic Usage¶
struct my_struct
{
int x = 10;
std::string name = "example";
double value = 3.14;
bool active = true;
std::string password = "secret"; // Don't serialize this!
};
my_struct obj{};
std::string buffer;
// Exclude specific keys at runtime
std::vector<std::string> exclude = {"password"};
auto ec = glz::write_json_exclude(obj, exclude, buffer);
// Result: {"x":10,"name":"example","value":3.14,"active":true}
Key Order¶
The output key order matches the struct definition order (not the exclude list order):
std::vector<std::string> exclude = {"name"};
glz::write_json_exclude(obj, exclude, buffer);
// Result: {"x":10,"value":3.14,"active":true,"password":"secret"}
// Keys appear in struct order: x, value, active, password (name excluded)
Supported Key Containers¶
Any range of string-like types works:
// std::vector<std::string>
std::vector<std::string> exclude1 = {"password", "internal_id"};
// std::vector<std::string_view>
std::vector<std::string_view> exclude2 = {"password", "internal_id"};
// std::array
std::array<std::string_view, 2> exclude3 = {"password", "internal_id"};
Error Handling¶
If an exclude key doesn't exist in the struct, error_code::unknown_key is returned:
std::vector<std::string> exclude = {"nonexistent"};
auto ec = glz::write_json_exclude(obj, exclude, buffer);
if (ec.ec == glz::error_code::unknown_key) {
// Handle unknown key error
}
Empty Exclude List¶
An empty exclude list writes all fields (equivalent to regular write_json):
std::vector<std::string> exclude = {};
glz::write_json_exclude(obj, exclude, buffer);
// Result: {"x":10,"name":"example","value":3.14,"active":true,"password":"secret"}
Excluding All Keys¶
Excluding all keys produces an empty JSON object:
std::vector<std::string> exclude = {"x", "name", "value", "active", "password"};
glz::write_json_exclude(obj, exclude, buffer);
// Result: {}
Duplicate Exclude Keys¶
Duplicate exclude keys are handled gracefully (the key is just excluded once):
std::vector<std::string> exclude = {"password", "password"};
glz::write_json_exclude(obj, exclude, buffer);
// Result: {"x":10,"name":"example","value":3.14,"active":true}
Options Support¶
Runtime exclude write supports standard Glaze options like prettify:
std::vector<std::string> exclude = {"password"};
glz::write_json_exclude<glz::opts{.prettify = true}>(obj, exclude, buffer);
// Result:
// {
// "x": 10,
// "name": "example",
// "value": 3.14,
// "active": true
// }
Return Types¶
Three overloads are available:
// 1. Write to resizable buffer (std::string, std::vector<char>)
error_ctx write_json_exclude(T&& value, const Keys& exclude_keys, Buffer&& buffer);
// 2. Write to raw buffer (char*)
expected<size_t, error_ctx> write_json_exclude(T&& value, const Keys& exclude_keys, Buffer&& buffer);
// 3. Return a new string
expected<std::string, error_ctx> write_json_exclude(T&& value, const Keys& exclude_keys);
Works with Reflectable Types¶
Runtime exclude write works with both explicit Glaze metadata and pure reflection (C++ aggregates):
// No glz::meta needed - pure reflection
struct reflectable_struct
{
int field1 = 100;
std::string field2 = "test";
std::string internal = "hidden";
};
reflectable_struct obj{};
std::vector<std::string> exclude = {"internal"};
glz::write_json_exclude(obj, exclude, buffer);
// Result: {"field1":100,"field2":"test"}
Choosing Between Approaches¶
| Feature | Compile-Time | Runtime Partial (Whitelist) | Runtime Exclude (Blacklist) |
|---|---|---|---|
| Function | write_json<partial> |
write_json_partial |
write_json_exclude |
| Key specification | constexpr JSON pointers |
Runtime container | Runtime container |
| Nested paths | Supported | Top-level keys only | Top-level keys only |
| Performance | Zero overhead | Hash lookup per key | Hash lookup per exclude key |
| Output order | Specified order | Input container order | Struct definition order |
| Use case | Fixed field sets | Include specific fields | Exclude specific fields |
Use compile-time partial write when: - The fields to serialize are known at compile time - You need nested JSON pointer paths - Maximum performance is critical
Use runtime partial write (whitelist) when: - The fields to serialize depend on runtime conditions - Different message types need different field subsets - User configuration determines which fields to include - You want control over the output key order
Use runtime exclude write (blacklist) when: - You want to serialize most fields but exclude a few - Excluding sensitive fields (passwords, tokens, internal IDs) - The set of excluded fields is smaller than the set of included fields - You want keys in struct definition order