Skip to main content

JSON API Contracts

What this concept is​

An API contract states what requests mean and which responses a consumer can accept. In our client, success requires the expected status, media type, bounded UTF-8 body, JSON shape and application values. Every check answers a different question.

Why it matters here​

The same validation discipline you used for files now protects a network boundary. A server is another program and can fail, change or send unexpected data.

Concrete example​

Our endpoint promises exactly {"sessions": [25, 15, 25]}: one named field containing integer minutes 1–240. The client returns count 3 and total 65. {"sessions": [true]} parses, but JSON true becomes Python True and must be rejected. {"sessions": [25.0]} is also rejected because this contract requires integers, not merely numerically equal values.

We ignore media-type parameters after ; and compare the media type case-insensitively. A response labeled text/html is rejected even if its bytes happen to parse as JSON. Unknown object fields are rejected by this small teaching schema; later compatibility work will explore alternative policies.

Common confusion / misconception​

Parsing does not validate meaning. “Be liberal in what you accept” is not permission to guess silently. A strict schema is a chosen policy; explain it instead of treating it as a universal API design rule.

How to use it​

Write the checks in their boundary order. Keep transport separate from interpretation so tests can supply response bytes without a server. Bound reads to the limit plus one byte. Preserve duplicates because they represent separate sessions. On failure, do not synthesize an empty successful response.

Check yourself​

Are [], {"sessions": []} and a missing response equivalent? No. Only the second is a successful empty history under this contract.

Mini drill or application​

Create one fixture failing each boundary while keeping the others valid. Explain why a checker that tests only malformed JSON would miss type, range and status defects.

Read this only if stuck​

Python JSON documentation gives parsing behavior; MDN HTTP gives the response context. The exact schema belongs to our README.