C++ JSON Parsing: nlohmann/json, RapidJSON, Custom Types, and Production Safety

C++ JSON Parsing: nlohmann/json, RapidJSON, Custom Types, and Production Safety

이 글의 핵심

Avoid crashes from missing keys, null, and type mismatches: safe access patterns, both major libraries, custom serialization, retries, and memory-conscious parsing for large payloads.

Introduction: parsing API responses without crashing

Typical failures: type mismatch ("age": 30 vs "30"), missing keys (j["opt"] inserts null), parse_error on bad JSON, memory doubling when loading huge strings, and manual struct mapping errors.

Goals: master nlohmann/json and RapidJSON patterns, custom types, error taxonomy, and streaming for large inputs.


Library comparison

Topicnlohmann/jsonRapidJSON
StyleSTL-likeExplicit C-style API
SpeedTypicalVery fast
MemoryHigherLower; SAX
Custom typesto_json / from_jsonManual
ErrorsExceptionsHasParseError()

nlohmann: parse string and file

Use json::parse in try/catch; prefer contains, value(key, default), at, and is_* before get<T> to avoid type_error.

Nested objects: check each level with contains before descending.


RapidJSON: Document and streams

Use Parse, check HasParseError(), GetParseError_En, GetErrorOffset(). Use HasMember, IsString, GetString, etc. For files, FileReadStream reduces peak memory vs loading a giant std::string first.


Custom types (nlohmann)

Implement void from_json(const json&, T&) and void to_json(json&, const T&) or NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE for simple POD-like structs. Handle optional and enums with explicit string mapping.


Common errors

  1. type_error: validate with is_number_integer, is_string, or coerce carefully.
  2. Missing key / null: use value, contains, find, never blind j["x"] for optional data.
  3. parse_error: catch and log e.byte.
  4. Memory: stream or SAX for multi-MB JSON.
  5. UTF-8: ensure files and HTTP responses are UTF-8.
  6. Threads: do not share mutable json across threads without synchronization—copy or parse per thread.

Performance (rule of thumb)

Library~1 MB parseMemory
nlohmann~50–80 ms (env-dependent)baseline
RapidJSON DOMfaster~0.5×
RapidJSON SAXfastest~0.2×

Choose nlohmann unless profiling says otherwise.


Production checklist

  • Catch parse_error and exception from nlohmann.
  • Validate with contains / value / at and is_*.
  • Cap message sizes; log failures without leaking PII.
  • Retry network fetch separately from parse (bad JSON should not retry forever).

  • HTTP client #21-1
  • nlohmann deep dive #27-2
  • Sockets #28-1

Next: Concepts #22-1

Previous: HTTP client #21-1