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
| Topic | nlohmann/json | RapidJSON |
|---|---|---|
| Style | STL-like | Explicit C-style API |
| Speed | Typical | Very fast |
| Memory | Higher | Lower; SAX |
| Custom types | to_json / from_json | Manual |
| Errors | Exceptions | HasParseError() |
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
- type_error: validate with
is_number_integer,is_string, or coerce carefully. - Missing key / null: use
value,contains,find, never blindj["x"]for optional data. - parse_error: catch and log
e.byte. - Memory: stream or SAX for multi-MB JSON.
- UTF-8: ensure files and HTTP responses are UTF-8.
- Threads: do not share mutable
jsonacross threads without synchronization—copy or parse per thread.
Performance (rule of thumb)
| Library | ~1 MB parse | Memory |
|---|---|---|
| nlohmann | ~50–80 ms (env-dependent) | baseline |
| RapidJSON DOM | faster | ~0.5× |
| RapidJSON SAX | fastest | ~0.2× |
Choose nlohmann unless profiling says otherwise.
Production checklist
- Catch
parse_errorandexceptionfrom nlohmann. - Validate with
contains/value/atandis_*. - Cap message sizes; log failures without leaking PII.
- Retry network fetch separately from parse (bad JSON should not retry forever).
Related posts
- HTTP client #21-1
- nlohmann deep dive #27-2
- Sockets #28-1
Next: Concepts #22-1
Previous: HTTP client #21-1