JSON — JavaScript Object Notation — is a text format for structured data with a grammar small enough to fit on a page: objects, arrays, strings, numbers, true, false and null. It has no schema, no comments, no date type, no integer type and no way to express a reference. That minimalism is why it became the default interchange format for HTTP APIs, configuration files, log records, message payloads, infrastructure state and CI pipeline definitions across every language and runtime in use.
The same minimalism is the source of the problems. Because JSON carries no schema, nothing in the format tells you whether a field is required, what values it may hold, or whether removing it breaks a consumer. Because numbers are doubles by specification, a 64-bit identifier can silently lose precision crossing a language boundary. Because there are no comments and no trailing commas, hand-edited configuration files break in ways that are trivial to cause and tedious to diagnose. And because duplicate keys and key ordering are underspecified, two parsers can legitimately disagree about the same document.
The discipline that fixes this is JSON Schema, and everything built on it. A schema states the shape a document must have, validators enforce it, editors use it for completion, CI uses it as a gate, and OpenAPI uses a subset of it to define the request and response contract of an entire API. Around that sit the operational tools: jq for querying and transforming, JSON Pointer and JSON Patch for addressing and modifying documents precisely, JSON Lines for streaming records, and structured JSON logging for machine-readable operations. Treated as a contract rather than a convenience, JSON stops being a source of production surprises.
Why this skill matters now
Almost every integration an organisation owns is a JSON document crossing a boundary. Service-to-service calls, webhooks, event payloads, Terraform state, Kubernetes manifests rendered from JSON, CI configuration, feature flags, audit logs and cloud API responses are all JSON, and each one is a contract that two systems have agreed on — usually informally, and usually only in documentation that has drifted.
The cost of that informality is measurable. Contract drift is one of the most common causes of integration incidents: a field is renamed, a type changes from string to number, an optional field becomes required, and the failure surfaces in someone else's service at deployment time. Configuration is worse still, because a malformed or semantically invalid config file usually fails at start-up in production rather than in review, where a schema would have caught it in seconds.
What closes the gap is treating schemas as code. Publishing a schema alongside every API and every config format, validating in CI, generating client types from the contract, and running compatibility checks before a change merges turns an entire class of incidents into build failures. That is engineering practice rather than syntax, and it is what this course teaches.