Skip to content

Partial Write

Glaze supports partial object writing, allowing you to serialize only specific fields. There are three approaches:

  1. Compile-time partial write - Uses JSON pointers as template parameters (zero runtime overhead)
  2. Runtime partial write (whitelist) - Specify keys to include at runtime
  3. 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:

std::vector<std::string> keys = {};
glz::write_json_partial(obj, keys, buffer);
// Result: {}

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