hypercontract is a concept for describing RESTful Web APIs using profiles written in RDF.
This workspace contains the source code of a prototype implementation of this concept. It consists of two applications:
- hypercontract - a web server that publishes the hypercontract RDF vocabulary
- hypershop - a demo application with an REST API documented with hypercontract
git clone https://github.com/hypercontract/hypercontract.git
cd hypercontract
npm installRun npm start and browse to...
- http://localhost to open hypershop
- http://localhost/profile to open the hypershop API documentation
- http://localhost:8080 to open the hypercontract vocabulary documentation
npm test- Run E2E testsnpm start, thennpm run test-postman- run Postman tests
Alternatively, you can import Postman collections from /postman into your Postman application.
The project is written in TypeScript and set up as an Nx Workspace consisting of two applications and two libraries.
hypercontract
hypercontract is a web application built with NestJS, using Express under the hood. Its only purpose is to publish the hypercontract RDF vocabulary at https://hypercontract.org.
hypershop
hypershop is a web application, also built with NestJS and Express. It serves as a demo to showcase how to describe a RESTful Web API using hypercontract. For this, it serves a simple online shop offering a catalog of randomly generated products that can be added to a shopping cart to place a new order.
The functionality of hypershop can be accessed through the browser as HTML representations or using an HTTP client as JSON, JSON-HAL or JSON-LD
All examples in this walkthrough can also be executed locally. Just replace the URLs accordingly:
The hypershop REST API supports JSON, JSON-HAL and JSON-LD as well as HTML. All requests in against the API can be executed in either of these formats.
- JSON (
application/json) - JSON-HAL (
application/hal+json) - JSON-LD (
application/ld+json) - HTML (
text/html)
Request the API Root as JSON-HAL.
GET https://example.hypercontract.org
Accept: application/hal+json
Requests with other media types fail with a 406 Not Acceptable response.
GET https://example.hypercontract.org
Accept: application/xml
The hypershop REST API also supports Content Negotiation by Profile.
Request the API Root according to the hypershop profile (https://example.hypercontract.org/profile).
GET https://example.hypercontract.org
Accept: application/ld+json
Accept-Profile: <https://example.hypercontract.org/profile>
Requesting a profile not supported by the application fails with a 406 Not Acceptable response.
GET https://example.hypercontract.org
Accept: application/ld+json
Accept-Profile: <https://example.org>
Open the hypershop profile in your browser.
Note that...
- the Entry Point of the API is defined as
https://example.hypercontract.org - the Entry Point URL returns an ApiRoot resource
- the Default Namespace of the API is defined as
https://example.hypercontract.org/profile/
This means that...
- the only URL we need to know is the entry point URL
- we can look up the
ApiRootdefinition to find out what we'll get when accessing the entry point - all descriptors can be dereferenced via their URIs by prefixing them with the default namespace.
You can also request a machine-readable version in various RDF formats:
- JSON-LD (
application/ld+json) - RDF/XML (
application/rdf+xml) - Turtle (
text/turtle) - N-Triples (
application/n-triples) - N-Quads (
application/n-quads) - TriG (
application/trig)
GET https://example.hypercontract.org/profile
Accept: application/hal+json
Open the ApiRoot definition in your browser.
From the ApiRoot resource there are four possible state transitions identified by these link relation types:
- to the Order History via
orderHistory - to the Shopping Cart via
shoppingCart - to the User Profile via
userProfile - via the
searchCatalogoperation
You can also request a machine-readable version of all profile concepts.
GET https://example.hypercontract.org/profile/ApiRoot
Accept: application/hal+json
You can learn more a about any profile concept by prefixing the name with the default namepspace.
Open the searchCatalog definition in your browser.
The definition of the searchCatalog operation tells us that the state transition...
- is performed by a GET request against the link target
- the link target is a
SearchResultsresource - the request requires query parameters described by the
SearchQueryclass
Open the SearchQuery definition in your browser.
The SearchQuery definition only refers to a queryString property of type string which is a...
A free-text search term that is used to search the catalog for Products. It is matched against the product name and the product description.
As the SearchQuery class describes the query parameters of the searchCatalog operation, we need to know how to serialize this type as a query parameter. The profile specifies this using application/td+xml schema describing a URI template of type text/uri-list:
https://example.hypercontract.org/products{?queryString}
Open the SearchResults definition in your browser.
The definition tells us that the representation returned when performing the searchCatalog operation will contain the total number of results in a totalResults descriptor as well as a list of Product representations identified by the products descriptor.
It also describes how the SearchResults resource is serialized using JSON Schemas for
application/hal+jsonapplication/jsonapplication/ld+json
Search the catalog by requesting search results as JSON-LD.
GET https://example.hypercontract.org/products/?queryString=pizza
Accept: application/ld+json
The response contains a list of Products, each uniquely identified through the JSON-LD-specific @id property. Every product also has a addToShoppingCart descriptor.
Open the addToShoppingCart definition in your browser.
addToShoppingCart is an Operation like searchCatalog. However, this time the state transition
- requires a POST request
- expects a request body matching the
AdditionToShoppingCartconcept - returns a representation of the
ShoppingCartresource - (even though the target of the state transition is the
ShoppingCartItemsresource)
Open the AdditionToShoppingCart definition to learn how to build the request body for the addToShoppingCart operation.
Open the ShoppingCart definition to learn what response to expect when performing the operation.
Use everything you learned to add a product to the shopping cart.
POST https://example.hypercontract.org/shoppingCart/items
Accept: application/ld+json
Content-Type: application/json
{
"product": "https://example.hypercontract.org/products/3c6118c5-ef72-4cfa-a767-933127c6e679",
"quantity": 2
}
