Specification
JSON Hyper-Schema
Introduction
JSON Hyper-Schema is an extension of JSON Schema that allows for the definition of hypermedia-driven APIs. The hyper-schema vocabulary shows how to annotate JSON documents with hypermedia controls by enabling the description of links and actions that can be executed on JSON data. Consecutively, it helps provide a more interactive and dynamic representation of JSON data. It also enhances API discoverability using the description features of actions and links within the JSON documents.
JSON Hyper-Schema seamlessly integrates with existing JSON HTTP APIs and offers functionalities to describe complex resource relationships, facilitate client-side validation, and promote better interaction patterns. It makes APIs more intuitive, self-descriptive, and efficient, particularly in RESTful architectures.
In essence:
- JSON Hyper-Schema is helpful in complex APIs where clients need to define and explicitly understand the relationships between resources and actions, especially when navigating resources without prior knowledge of the API structure.
- It helps create more discoverable and self-documenting APIs, making it easier for clients to interact with them.
Hyper-schema use cases
Basic concept
Get a JSON instance
1GET https://example.com/book/12345This GET request fetches information about a specific book, identified by the book ID (12345). In response:
1200 OK
2Content-Type: application/json
3Link: <https://example.com/schemas/book>; rel="describedby"
4
5{
6 "title": "Mobby-Dick",
7 "authorId": 100,
8 ...
9}The server responds with a successful 200 OK status, JSON-formatted data, and a Link header that references the schema describing the structure of the returned data, including details like the book title and a link to the author via authorId.
Get the schema that describes the instance using the "describedby" Link header.
1GET https://example.com/schemas/bookThis request fetches the schema describing the structure of the book object.
In response:
1200 OK
2Content-Type: application/schema+json
3
4{
5 "links": [
6 {
7 "href": "/author/{authorId}",
8 "rel": "author",
9 "templateRequired": ["authorId"]
10 }
11 ]
12}The response contains a JSON Schema describing the instance's structure and links to relevant resources, such as the author's resource via rel="author." It also specifies that the authorId is required to complete the URL template.
Use the LDO combined with the instance to construct a link to get information about the author.
1GET https://example.com/author/100This request fetches data for the author with authorId 100. In response:
1200 OK
2Content-Type: application/json
3Link: <https://example.com/schemas/author>; rel="describedby"
4
5{
6 "name": "Herman Melville",
7 ...
8}The response includes a JSON object with the author's details, and the Link header points to the schema that describes the author, following the same format as the book schema.
Keep following links to discover more content.
Actions
Search
Using a link to construct a URI from user input. (Analogous to <form method="get">)
1GET https://example.com/books?title=Moby-DickThis GET request searches for books with the title Moby-Dick.
1200 OK
2Content-Type: application/json
3Link: <https://example.com/schemas/books>; rel="describedby"
4
5[
6 {
7 "title": "Mobby-Dick",
8 "authorId": 100,
9 ...
10 }
11]The response returns a successful 200 OK JSON-formatted data with a Link to the schema describing the book collection, and the response body contains an array of books, each with details such as the title and authorId.
Submission
Using a link to submit user input. (Analogous to <form method="post">)
1POST https://example.com/books
2Content-Type: application/json
3
4{
5 "title": "Moby-Dick",
6 "authorId": 100,
7 ...
8}This POST request submits data to create a new book with the title "Moby-Dick" and authorId 100.
1204 No ContentThe request was successful, and the book was created, but the response contained no content.
Submission Media Type
You can also make submission will media types other than JSON.
1POST https://example.com/books
2Content-Type: application/xml
3
4<Book>
5 <title>Moby-Dick<title>
6 <authorId>100</authorId>
7 ...
8</Book>1204 No ContentThis code shows using application/xml, to create a new book resource with a POST request.
Relations
Registered relation
A registered relation pointing to an author.
Custom relation
A custom relation linking to a specific review.
Multiple relations
A multiple relations associating a comments collection with two different relationship types.
Base URIs
A base URI is used to resolve relative URIs.
Default
By default, the base URI for relative URIs in LDOs is the URI used to retrieve the resource
1GET https://example.com/books/1Link Target: https://example.com/author/1
Setting the base URI
base can be used to alter the base URI. It is a URI Template and can be relative.
1GET https://example.com/myapi/v3/books/1Link Target: https://example.com/myapi/v3/author/1
Setting a link's "anchor"
A link is a connection between two resources. The source of the link is called the "anchor" and the destination is called the "target. The "anchor" usually doesn't need to be specified because it's understood to be the resource the link appears in. anchor allows you to change the link's "anchor" to something other than the resource it appears in.
When anchor appears in an LDO, it becomes the base URI for resolving href.
NOTE: I don't have an example because I can't think of any reason someone would want to do this. It's an anti-pattern at best. It might be best to just leave anchor and anchorPointer undocumented.
URI Templates
href, base, and anchor are URI Templates
Template variables
Link applicability
about: N/A
Note: Links are annotations, which means they're attached to a location in the JSON instance. If the location of the link doesn't exist in the JSON instance, the link doesn't apply.
about: https://example.com/docs
Required/Optional variables
next: https://example.com/books?page=1
previous: N/A
Note: previous doesn't apply because the required property "previous" is not present.
Note: perPage is an optional variable. The next link still applies even though there is no "perPage" property.
next: https://example.com/books?page=1&perPage=2
previous: N/A
Note: Optional variable perPage is present and included in the link.
Variable coersion
https://example.com/relations/a: https://example.com/true
https://example.com/relations/a: https://example.com/false
https://example.com/relations/a: https://example.com/null
https://example.com/relations/a: https://example.com/42
Pointers
Expand a variable from a different object.
https://example.com/relations/cart-item: https://example.com/cart-item/100/200
Example using Relative JSON Pointer instead of JSON Pointer.
https://example.com/relations/cart-item: https://example.com/cart-item/100/200
TODO
- PUT and DELETE
titledescriptiontargetMediaTypetargetSchematargetHintsheaderSchema- Special case relations:
collection/item,root,self
Hyper Schema Specification
- Hyper-Schema: draft-handrews-json-schema-hyperschema-02
- Relative JSON Pointer: draft-bhutton-relative-json-pointer-00
Schemas:
- JSON Hyper-Schema meta-schema
- JSON Hyper-Schema vocabulary schema
- JSON Hyper-Schema Link Description Object meta-schema
- JSON Schema Output schemas and examples
Release Notes
Need Help?
Did you find these docs helpful?
Help us make our docs great!
At JSON Schema, we value docs contributions as much as every other type of contribution!
Still Need Help?
Learning JSON Schema is often confusing, but don't worry, we are here to help!.