CodeRigor

FREE LESSON

JSON and runtime validation

Separate JSON syntax from application schema and return normalized records with explicit failure classes.

JSON is a text representation of values. Parsing converts that text into JavaScript values; validation decides whether those values belong in your application. A successful parse says nothing about the presence of an id, the allowed states, duplicate identifiers or numeric bounds. Keep those two boundaries separate so failures remain understandable.

JavaScript
const values = [JSON.parse("null"), JSON.parse("[]"), JSON.parse('{"duration":"2"}')];
console.log(values[0] === null);
console.log(Array.isArray(values[1]));
console.log(typeof values[2].duration);

JSON distinguishes strings and numbers. Automatically converting a duration string to a number widens the accepted schema and can hide upstream mistakes. For this build, a duration must already be a number. Check its type, finiteness and nonnegative range before using it in arithmetic. Even valid numeric JSON such as 1e400 can overflow into JavaScript Infinity, so syntax alone does not establish finiteness.

Two distinct validation boundaries
start / 4
Syntax, schema and normalized identity are separate checks.
Two distinct validation boundaries
Syntax, schema and normalized identity are separate checks.

Validate shape before accessing fields. typeof null is object, and arrays are objects too. Exclude null and arrays explicitly, then check each required field. A missing property reads as undefined, which should fail the appropriate field test. Avoid replacing a missing or malformed field with a convenient default unless the schema explicitly permits that default.

Normalization is a separate decision from acceptance. This interface trims id whitespace, accepts only two exact state strings, and ignores unknown fields. Returning an explicitly constructed record limits downstream data to the agreed fields. Blindly spreading every input property would preserve extras that the public result promises to remove.

JavaScript
const raw = {id: " job-1 ", state: "ok", duration: 0, debug: "extra"};
const normalized = {id: raw.id.trim(), state: raw.state, duration: raw.duration};
console.log(JSON.stringify(normalized));
Normalize before checking uniqueness
start / 1
Both spellings become the same application identity.
Normalize before checking uniqueness
Both spellings become the same application identity.

Deduplication must use the normalized identity. Raw ids "job" and " job " are different strings but become the same application id. Insert and look up the same trimmed value in a Set. Otherwise the outcome depends on the spelling and encounter order instead of the intended uniqueness rule. Empty arrays are valid; an empty trimmed id is not.

The failure classes form a small diagnostic vocabulary: SyntaxError for malformed JSON, TypeError for the wrong schema and RangeError for duplicate normalized ids. Let JSON.parse produce its own syntax failure, and throw the documented application errors where validation detects them. Do not log inside this reusable function.

For practice, begin with one valid record and change exactly one property at a time. Try a null record, an array record, an empty id, an unknown state, a string duration and an overflowing numeric literal. Then test two ids that collide only after trimming. These cases demonstrate why a typed language added later would still need runtime validation at an external text boundary.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Focus on JSON values, arrays, objects and syntax. The build goes further by enforcing an application schema after parsing.