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/12345
This 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/book
This 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/100
This 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-Dick
This 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 Content
The 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 Content
This 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/1
Link 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/1
Link 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
title
description
targetMediaType
targetSchema
targetHints
headerSchema
- 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!.