Component of the Week #39: baljsn_simpleformatter
- Summary:
Provides a simple formatter for encoding data in the JSON format.
Need to generate JSON output programmatically? Building a REST API response or
creating configuration files? The
baljsn_simpleformatter
component provides baljsn::SimpleFormatter, a class that makes it easy to
construct well-formed JSON documents with a clean, intuitive API.
Why “Simple”?
BDE already has baljsn::Formatter, a lower-level, stateless formatter.
SimpleFormatter tracks state internally, so you don’t need to manually call
openMember()/closeMember() or add array separators - it handles all the
bookkeeping automatically. Compare:
// Using baljsn::Formatter
formatter.openObject();
formatter.openMember("name");
formatter.putValue("Alice");
formatter.closeMember();
formatter.openMember("age");
formatter.putValue(30);
// Must remember NOT to call closeMember here!
formatter.closeObject();
// Using baljsn::SimpleFormatter
formatter.openObject();
formatter.addValue("name", "Alice");
formatter.addValue("age", 30);
formatter.closeObject();
Formatting Options
By default, SimpleFormatter produces compact JSON. For human-readable
output, enable pretty-printing with EncoderOptions:
baljsn::EncoderOptions options;
options.setEncodingStyle(baljsn::EncoderOptions::e_PRETTY);
options.setSpacesPerLevel(2);
baljsn::SimpleFormatter formatter(bsl::cout, options);
formatter.openObject();
formatter.addValue("name", "Bob");
formatter.addValue("age", 25);
formatter.closeObject();
// Output:
// {
// "name": "Bob",
// "age": 25
// }
Working with Arrays
Arrays work similarly - just open and close them. Array elements don’t have names:
baljsn::SimpleFormatter formatter(bsl::cout);
formatter.openArray();
formatter.addValue(1);
formatter.addValue(2);
formatter.addValue(3);
formatter.closeArray();
// Output: [1,2,3]
Nested Structures
Objects and arrays can be nested arbitrarily. Named fields use one overload, unnamed array elements use another:
baljsn::SimpleFormatter formatter(bsl::cout);
formatter.openObject();
formatter.addValue("name", "Alice");
// Named array inside object
formatter.openArray("scores");
formatter.addValue(95);
formatter.addValue(87);
formatter.addValue(92);
formatter.closeArray();
// Named nested object
formatter.openObject("address");
formatter.addValue("city", "New York");
formatter.addValue("zip", "10001");
formatter.closeObject();
formatter.closeObject();
// Output: {"name":"Alice","scores":[95,87,92],"address":{"city":"New York","zip":"10001"}}
Type Safety
SimpleFormatter uses templates for addValue(), so it works with any
type that baljsn::PrintUtil knows how to format - strings, numbers, bools,
and many BDE types like bdlt::Datetime, bdldfp::Decimal64, etc.
Comparison to Alternatives
vs. baljsn::Formatter:
SimpleFormattertracks state and handles formatting automatically, making it much easier to use.Formatteris stateless and gives you lower-level control - useful if you’re generating JSON incrementally across different functions or need precise control over output, but requires manual state management.vs. bdljsn::Json:
SimpleFormatterwrites directly to a stream without building an in-memory DOM, making it more efficient for large documents.vs. manual string concatenation: Proper escaping, type-safe, and guaranteed well-formed JSON.
For more information, check out the documentation for baljsn_simpleformatter.