Reference Overview
This overview introduces the semantic web concepts and technologies that underpin the WhenFresh API.
JSON-LD
The API returns requested resources in the JSON-LD linked data format that allows JSON documents to be enriched with schemas describing data structures and data types.
A typical JSON-LD response for a postal addresses search looks like this:
{
"@context" : "https://api.whenfresh.com/.hydra/context.jsonld",
"@type" : "hydra:Collection",
"totalItems" : 2,
"member" : [
{
"catalog" : {
"@type" : "Catalog",
"@id" : "https://api.whenfresh.com/world/gb/addresses/8e05h·0/catalog"
},
"@id" : "https://api.whenfresh.com/world/gb/addresses/8e05h·0",
"label" : "1 Spa Mews",
"@type" : "PostalAddress"
},
{
"@type" : "PostalAddress",
"catalog" : {
"@id" : "https://api.whenfresh.com/world/gb/addresses/8e05i·0/catalog",
"@type" : "Catalog"
},
"@id" : "https://api.whenfresh.com/world/gb/addresses/8e05i·0",
"label" : "2 Spa Mews"
}
]
}
The following subsections explain the anatomy of this JSON.
Metadata
The @
symbol signifies a piece of metadata such as an @id
(the primary key-like unique URI of the resource) or an @type
(the type of resource).
In this case, a collection ("@type" : "hydra:Collection"
) contains several postal addresses ("@type" : "PostalAddress"
) which each have a catalog ("@type" : "Catalog"
) with a unique @id
URI.
Properties
Each object described by JSON has a set of properties, which are:
- Simple properties such as the simple string
"label" : "1 Spa Mews"
. - Typed properties which have a type such as
"@type" : "PostalAddress"
. - Sub-resources which have a type such as
"@type" : "Catalog"
and are linked to a separate resource that can be navigated via its unique URI ID such as"@id" : "https://api.whenfresh.com/world/gb/addresses/8e05h·0/catalog"
.
Collections
Collections are of type hydra:Collection
and they have the following properties:
- a
member
list of contained resources. - a
totalItems
property as a count of the number of items in the collection.
Our example JSON-LD contains a collection of PostalAddress
members.
Collections may be paged so that they do not return all items at once, in which case the following view
JSON will indicate the current page along with links to the first page, last page, next page and previous page.
"view": {
"@id": "http://api.example.com/an-issue/comments?page=3",
"@type": "PartialCollectionView",
"first": "/an-issue/comments?page=1",
"previous": "/an-issue/comments?page=2",
"next": "/an-issue/comments?page=4",
"last": "/an-issue/comments?page=498"
}
Media types
Currently the API returns JSON-LD, but this cannot be assumed in future when we support additional media types. Therefore, any HTTP requests should include the accept header -H "Accept: application/ld+json"
to ensure that the correct response format is returned.
Hydra and hypermedia
Hydra complements JSON-LD by providing a vocabulary for hypermedia-driven web APIs, thus enabling the creation of generic API clients that can navigate between resources and perform operations on them. Our main motivation for using Hydra is to provide developers with an API browser.
API entry point
The API's Hydra entry point at https://api.whenfresh.com/
returns JSON-LD as shown next, which describes what you can do with the API:
{
"@id" : "https://api.whenfresh.com/",
"@context" : "https://api.whenfresh.com/.hydra/context.jsonld",
"@type" : "hydra:EntryPoint",
"collection" : [
{
"@id" : "https://api.whenfresh.com/world/GB/addresses/",
"manages" : {
"property" : "rdf:type",
"object" : ":PostalAddress"
},
"@type" : "hydra:Collection",
"search" : {
"template" : "/world/GB/addresses/{?postcode}",
"@type" : "hydra:IriTemplate",
"variableRepresentation" : "BasicRepresentation",
"mapping" : [
{
"variable" : "postcode",
"required" : true,
"property" : "hydra:freetextQuery"
}
]
}
}
]
}
In this case it returns a single Hydra collection that manages PostalAddress
objects and has a search
property that allows you to search for addresses in a particular postcode area.
The search
property has a template
that determines how the search URIs are crafted dynamically by (in this case) incorporating the postcode
free text variable.
Note
The purpose of this reference material is not to tell you how to craft such URIs, but to tell you how to find out (from the API) how to craft such URIs.
Resource documentation
Every resource returned by the API includes a link in the response header to the Hydra documentation for the resource:
link: <https://api.whenfresh.com/.hydra/documentation.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
The Hydra documentation at this link details all of the types that exist in the API. The following subset of the Hydra documentation shows that the Catalog
resource has a number of properties and (in particular) a supportedOperation
to purchase variables:
{
"supportedClass" : [
{
"supportedProperty" : [
{
"@type" : "hydra:SupportedProperty",
"property" : {
"@type" : "rdf:Property",
"@id" : "Catalog/variables"
}
},
{
"property" : {
"@type" : "rdf:Property",
"@id" : "Catalog/addressKey",
"range" : "xsd:string"
},
"@type" : "hydra:SupportedProperty"
},
{
"@type" : "hydra:SupportedProperty",
"property" : {
"@id" : "Catalog/countryCode",
"@type" : "rdf:Property",
"range" : "xsd:string"
}
}
],
"supportedOperation" : [
{
"@type" : "PurchaseVariableAction",
"expects" : "PurchaseVariableAction",
"title" : "Purchase variables",
"method" : "POST"
}
],
"@id" : "Catalog",
"@type" : "hydra:Class"
},
...
],
"@type" : "hydra:ApiDocumentation",
"@id" : "https://api.whenfresh.com/.hydra/documentation.jsonld",
"@context" : "https://api.whenfresh.com/.hydra/context.jsonld"
}
Operations
As with RESTful APIs, a resource's operations correspond with HTTP GET and POST requests. In the previous example, the "purchase variables" operation is invoked using the POST
method.
This particular operation is of type PurchaseVariableAction
which is defined as a property as follows:
{
"supportedProperty" : [
{
"@type" : "hydra:SupportedProperty",
"property" : {
"@type" : "rdf:Property",
"@id" : "PurchaseVariableAction/variables"
}
},
{
"property" : {
"@id" : "hydra:Operation/method",
"@type" : "rdf:Property",
"range" : "xsd:string"
},
"@type" : "hydra:SupportedProperty"
},
{
"@type" : "hydra:SupportedProperty",
"property" : {
"@id" : "hydra:Operation/expects",
"@type" : "rdf:Property",
"range" : "xsd:string"
}
},
{
"@type" : "hydra:SupportedProperty",
"property" : {
"range" : "xsd:string",
"@type" : "rdf:Property",
"@id" : "hydra:Operation/title"
}
}
],
"@type" : "hydra:Class",
"supportedOperation" : [],
"@id" : "PurchaseVariableAction"
}
Additional information
You might also be interested in: