Education · Jan 15, 2024
How to write JSON Schemas for your API Part 2: documenting fields
JSON Schema serves two purposes when used for APIs. The first is to [validate incoming data](Part 1). The second is to communicate to clients how they should format their data so it passes validation.
JSON Schema supports several meta-data keywords that don't participate in validation logic but help the developer to understand the schema.
Many documentation tools can take this meta-data and produce publishable documentation for developers.
title and description
Each schema can be given a title and description, which can be displayed by documentation or user interfaces. The title is typically a single line, whereas the description can contain paragraphs.
"description": "The contact object describes the contact information for a person associated with an account.\n\nAn account can have many contacts, and a single contact can belong to more than one account.",
Since most descriptions contain multiple lines of text, it can be helpful to write JSON schema as YAML instead of JSON because it supports line breaks
The contact object describes the contact information for a person associated with an account.
An account can have many contacts, and a single contact can belong to more than one account.
One of the most helpful ways to onboard new developers onto your API is to provide them with realistic examples, which they can copy and modify.
examples you can include illustrate or more use-cases using concrete examples. Most documentation websites will read this and display examples side-by-side with field-level documentation.
Here is a schema for addresse that includes examples for different regions.
line_1: 10 Example St
line_2: Apt 3
line_1: 3/10 Example St
In the case of optional data, the schema can be annotated with the value that the API will use by default.
This can make your API more ergonomic and simpler to use, similar to progressive disclosure.
Using the printer example, a print API can specify a default printer setting preset.
Or, if the user specifies a custom preset, they only need to specify the settings they care about.
Specifying a default also clarifies to the developer that the omission of an optional field is not an additional state, but rather equivalent to one of the existing states. For example, an optional boolean field without a default value could be interpreted by some APIs as either true, false or undefined as a third state.
When it comes to APIs, it is useful to share schemas between the requests and responses. However in practice there are some fields that should only appear in requests or only appear in responses. A good example is ID fields, which need to be generated by the server to ensure uniqueness. Create APIs usually should not require IDs.
You can use
readOnly to specify that the property only appears in responses.
description: A unique identifier for the object, generated by the server upon creation.
The advantage of specifying a field as read only is that you can reuse the same schema in both request and response contents. This allows developers to model the request and response using the same type in code.
writeOnly keyword is the opposite to the
readOnly keyword, as you would expect. Though there are fewer use cases.
An example of a field that should only appear in requests is a password field of a Reset Password flow. The server should be able to accept new passwords, but they should never appear in any response for security reasons.
API product lifecycle
APIs products have their own lifecycle just like other digital products. However, unlike web and mobile products, they have an additional constraint to ensure backwards compatibility and not break existing integrations.
A common way to strike this balance is to deprecate certain fields in your API. When you deprecate a field, it is still functional but communicates to developers that they should stop relying on it soon. (Your description should also include details on how to migrate away from using the field.)
This example shows an
is_active boolean field that has been deprecated in favor of a more flexible
Whether the user is active.
This field is deprecated and will be removed in a future version. Use the `status` instead.