API Architecture
AlpineBits® DestinationData specifies a REST API designed to support the client-server communication model, with a focus on system-to-system communication.
This API is built upon JSON:API v1.0, a specification containing best practices for the implementation of REST APIs that exchange JSON data over HTTP.
AlpineBits® DestinationData relies on its underlying transport protocol to take care of security issues. Hence the use of HTTPS is REQUIRED.
1. Server Responsibilities
A SERVER MUST be able to handle GET requests on the endpoints defined in this standard, replying with the appropriate HTTP status codes as defined in this document.
This standard does not encompass request messages for other HTTP methods, such as POST, PATCH, and DELETE, but the SERVER MAY implement them.
A SERVER MUST comply to the JSON:API v1.0 in all HTTP methods it implements.
2. Request Messages
A request message starts an interaction between a CLIENT and a SERVER, being sent by the former to the latter.
2.1. Message Headers
A GET request message MUST include the header Accept: application/vnd.api+json, which indicates that the request is for data serialized according to the media type defined in JSON:API v1.0.
A SERVER MAY support additional media types, such as application/json and application/xml.
A SERVER MUST respond with a 406 Not Acceptable status code if a request’s Accept header contains a media type it does not or with encoding parameters in application/vnd.api+json.
A SERVER MUST support authentication through the basic authentication mechanism.
The following example presents the Authorization header of a request using basic authentication.
GET /1.0/events HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
Authorization: Basic Y2hyaXM6c2VjcmV0
Note that the value of the Authorization header is the string john:secret encoded in base64 (Y2hyaXM6c2VjcmV0), as defined by the basic access authentication standard.
A SERVER MAY support additional authentication methods (e.g., OAuth, JSON Web Token, and OpenID Connect) or even non-authenticated requests.
If a SERVER does not support non-authenticated requests, it MUST reject them with response messages containing the HTTP status code 401 Unauthorized.
This same response MUST be returned if a request made using the basic authentication mechanism contains an invalid combination of username and password.
3. Response Messages
A response message closes an interaction between a CLIENT and a SERVER, being sent by the latter to the former in response to a previous request message.
If a response message includes a body, the SERVER MUST:
-
Encode this body in
UTF-8; and -
Include the following header in the message:
Content-Type: application/vnd.api+json.
Note that the SERVER MUST NOT add encoding parameters to the Content-Type header in order to enable compatibility with JSON:API v1.0 and its future releases.
A response message MUST include an appropriate HTTP status code.
Response messages are classified into Success Messages and Error Messages, which are detailed in the following subsections.
3.1. Success Messages
A success message is one that results from a successful request made to a SERVER.
3.1.1. Message Headers
A success message header MUST contain an HTTP status code in the class 2xx Success, as in:
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
3.1.2. Message Body
A success message MUST have a body, which described by the following fields:
-
data: an object or array of objects containing resource data. This field is mandatory, but when a response contains no data, it MUST be set to null.Refer to Resources for more details about the inner structure of this field.
-
links: an object containing links for navigating the API. Links are used for self-referencing, resource relationships, and pagination. This field is mandatory and non-nullable, as it MUST always contain aselflink for self-referencing.Refer to Pagination for more details.
-
jsonapi: an object describing the JSON:API version adopted by the SERVER. This field is optional but non-nullable. If set, it must contain the object{ "version": "1.0" }. -
meta: an object that contains metadata about its container. This field is optional but non-nullable. It is used, for instance, to share pagination data.Refer to Pagination for more details.
-
included: an array of resource objects included in the message that are related to those in thedatafield. This field is optional but non-nullable.See Inclusion of Related Resources for more details.
A success message body SHALL NOT have fields in addition to those listed above.
An overview of the basic structure of a success message body is depicted below:
{
"jsonapi": {
"version": "1.0"
},
"meta": { ... },
"data": ...,
"included": [ ... ],
"links": { ... },
}
The following request:
GET /1.0/mediaObjects?include=copyrightOwner HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
Authorization: Basic Y2hyaXM6c2VjcmV0
Could generate the following response message (header and body):
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"jsonapi": {
"version": "1.0"
},
"meta": {
"count": 10,
"pages": 10
},
"links": {
"next": "https://example.com/1.0/mediaObjects?page[number]=2",
"prev": "https://example.com/1.0/mediaObjects?page[number]=1",
"first": "https://example.com/1.0/mediaObjects?page[number]=1",
"last": "https://example.com/1.0/mediaObjects?page[number]=10",
"self": "https://example.com/1.0/mediaObjects"
},
"data": [
{
"type": "mediaObjects",
"id": "1",
"meta": {
"dataProvider": null,
"lastUpdate": null
},
"attributes": {
"abstract": null,
"contentType": "text/markdown",
"categories": null,
"description": null,
"duration": null,
"height": null,
"license": null,
"name": null,
"shortName": null,
"url": "http://example.com/description.md",
"width": null
},
"relationships": {
"copyrightOwner": {
"data": {
"type": "agents",
"id": "1"
},
"links": {
"related": "http://example.com/1.0/mediaObjects/1/copyrgihtOwner/"
}
}
},
"links": {
"self": "http://example.com/1.0/mediaObjects/1"
}
}
],
"included": [
{
"type": "agents",
"id": "1",
"meta": {
"dataProvider": null,
"lastUpdate": null
},
"attributes": {
"abstract": null,
"categories": null,
"contactPoints": null,
"dataProvider": null,
"description": null,
"lastUpdate": null,
"name": {
"eng": "Free University of Bozen-Bolzano"
},
"shortName": null,
"url": null
},
"relationships": {
"multimediaDescriptions": null
},
"links": {
"self": "http://example.com/1.0/agents/1"
}
}
]
}
|
3.2. Error Messages
An error message is one that results from an unsuccessful request made to a SERVER.
3.2.1. Message Headers
An error message header MUST contain an HTTP status code either in the class Client Error 4xx or the class Server Error 5xx, as in:
HTTP/1.1 401 Unauthorized
If a request message results in multiple errors, the status code in error message SHOULD be the most general status code applicable. For example, if a request results in the errors 415 Unsupported Media Type and 410 Gone, the header SHOULD contain the error code 400 Bad Request.
3.2.2. Message Body
This version of the standard does not define specific error scenarios. Thus, it is OPTIONAL for a SERVER to include a body in an error message.
If it does, the body MUST comply with the JSON:API v1.0. This means an object described by the following fields:
-
error: an array of error objects as defined in JSON:API v1.0. This version of the standard does not define specific error objects. This field is mandatory but non-nullable. -
jsonapi: an object describing the JSON:API version adopted by the SERVER. This field is optional but non-nullable. If set, it must contain the object{ "version": "1.0" }. -
meta: an object that contains non-standard meta-information about its container. This field is optional but non-nullable. -
links: an object containing links. This field is optional but non-nullable.
An error message body SHALL NOT have fields in addition to those listed above.
For more details on error message bodies, refer to the JSON:API v1.0 specification.
An overview of the basic structure of an error message body is depicted below:
{
"jsonapi": {
"version": "1.0"
},
"meta": { ... },
"error": [
{
"status": "404",
"title": "Endpoint not available"
}
],
"links": { ... }
}
The following example presents an error message (header and body) containing multiple error objects.
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json
{
"jsonapi": {
"version": "1.0"
},
"errors": [
{
"status": 404,
"title": "Resource not found."
},
{
"status": 405,
"title": "Method not supported."
}
]
}
|
3.3. Error Status Codes
A SERVER MUST reply with specific status codes in the following cases:
-
400 Bad Request: when a CLIENT uses unknown or invalid URL parameters in the request message. -
401 Unauthorized: when a CLIENT makes an authenticated request that failed which failed to be validated by the SERVER. -
404 Not Found: when a CLIENT makes a request for a non-existing resource or to a non-implemented endpoint. -
405 Method Not Allowed: when a CLIENT makes a request using an HTTP method that is not supported by the SERVER. -
406 Not Acceptable: when a CLIENT makes a request with anAcceptheader containing a media type not supported by the SERVER or with encoding parameters inapplication/vnd.api+json. -
410 Gone: when a CLIENT requests a resource that is no longer available in the SERVER (e.g. it may have been deleted).
4. API Features
The AlpineBits® DestinationData standard specifies a set of API features to be implemented by a SERVER. These features are intended to make the communication between CLIENTS and SERVERS more effective and efficient.
Four features are discussed, namely Hypermedia Controls, Pagination, Sparse Fieldsets, and Inclusion of Related Resources.
4.1. Hypermedia Controls
Hypermedia control is a strategy to encode resource navigation and manipulation within the messages exchanged through an API.
The AlpineBits® DestinationData standard adopts the hypermedia strategy defined in JSON:API v1.0, which is briefly described in the following paragraphs.
To provide hypermedia controls for CLIENTS to navigate the API, a SERVER MUST include a links objects according to what is defined in this standard.
A SERVER MUST use the endpoints it implements in order to refer to resources through links objects (e.g., in self and related links).
4.1.1. Action Discovery
SERVERS that support additional HTTP methods SHOULD support action discovery.
To do so, a SERVER needs to:
* Support HEAD requests on all of its endpoints
* Answer HEAD requests with messages containing an Allow header listing the HTTP methods it supports on the requested endpoint.
The following two snippets exemplify a HEAD request made by a CLIENT and its response sent by a SERVER.
HEAD /1.0/events HTTP/1.1
Host: https://example.com/
Authorization: Basic Y2hyaXM6c2VjcmV0
HTTP/1.1 200 OK
Allow: GET,POST,PATCH,DELETE
A response message to a HEAD request message does not contain a body.
4.2. Pagination
The pagination feature allows a CLIENT to request a subset of the resources available at any given endpoint.
The response message containing such a subset is referred to as a page.
A SERVER MUST implement pagination for GET requests in every base endpoint, such as /1.0/events and /1.0/mountainAreas.
The pagination strategy adopted in this standard uses two parameters:
-
page[size]: the number of resources included in a page. -
page[number]: the number of the page
The following request message exemplifies the use of pagination parameters:
GET /1.0/events?page[size]=10&page[number]=2 HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
The request asks for the second page (page[number]=2) in the collection of event resources, divided in pages containing 10 events each (page[size]=10).
Note that pagination parameters are included in a request as URL parameters in the request, i.e. by adding them to the URL after the ? character, as defined by the JSON:API v1.0 standard.
A CLIENT MAY include one or both pagination parameters in a request message.
The SERVER SHOULD define a default page size.
The SERVER MUST respond with the first page in case no pagination parameters are sent in the request.
In paginated responses, the SERVER MUST add the following fields to the links object in the message body:
-
first: a string that represents the URL to request the first page of resources in that endpoint. Non-nullable. -
last: a string that represents the URL to request the last page of resources in that endpoint. Non-nullable. -
self: a string that represents the URL to request the current page of resources in that endpoint. Non-nullable. -
next: a string that represents the URL to request the next page of resources in that endpoint. ThenextURL MUST be the same aslastin case the next page is out of bounds. Non-nullable. -
prev: a string that represents the URL to request the previous page of resources in that endpoint. TheprevURL MUST be the same asfirstin case the previous page is out of bounds. Non-nullable.
In paginated responses, the SERVER MUST add the following fields to the meta object in the message body:
-
count: a number that indicates the number of resources available in the endpoint. Non-nullable. -
pages: a number that indicates the number of resources pages in the collection according to the provided page size. Non-nullable.
The following message excerpt illustrates a response to the paginated request previously provided:
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"meta": {
"count": 1000,
"pages": 100
},
"links": {
"first": "https://example.com/1.0/events?page[number]=1",
"last": "https://example.com/1.0/events?page[number]=100",
"self": "https://example.com/1.0/events?page[number]=2",
"next": "https://example.com/1.0/events?page[number]=3",
"prev": "https://example.com/1.0/events?page[number]=1"
},
...
}
4.3. Sparse Fieldsets
The sparse fieldset feature allows a CLIENT to request a specific subset of resources' attributes and relationships fields given a resource type.
This features allows CLIENTS to receive smaller payloads in their responses by selecting only the date they want.
For example, in the following request, the CLIENT requests for agent resources, but only the attributes name and contactPoints:
GET /1.0/agents?fields[agents]=name,contactPoints HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
The SERVER MAY support sparse fieldsets according to the JSON:API v1.0 specification. The feature applies both to endpoints that return collections of resources, e.g. /1.0/events, and those that return individual resources, e.g. /1.0/events/123.
In order to select the fields they want, the CLIENT MUST append them as URL parameters in the request.
Each parameter is identified using the keyword fields with the resource type within brackets, as in fields[events] and fields[mediaObject].
The desired fields for each resource type follow the parameter definition, as in fields[events]=name,startDate,organizers and fields[mediaObject]=name,url,license.
4.4. Inclusion of Related Resources
The inclusion of related resources feature allows a CLIENT to request a SERVER to add, in a response message, the resources related to the base resource.
For example, a CLIENT may request a SERVER for event resources and to include agent resources that appear in the organizers field of the events in its response.
An example of a request asking for related resources is shown below:
GET /1.0/events?include=organizers HTTP/1.1
Accept: application/vnd.api+json
It is RECOMMENDED that the SERVER supports the inclusion of related resources.
In successful messages, the SERVER MUST add the related resources of requested relationships to the included array.
To ask for the inclusion of related resources, a CLIENT MUST append includes as a URL parameter of the request message.
The resources to be included are listed and separated by commas, as in /1.0/events?include=organizers,sponsors and /1.0/mountainAreas?include=trails,lifts,snowparks.
In order to request resources related to other resources, a dot-separated path for each relationship name can be specified, as in /1.0/events?include=organizers.multimediaDescriptions and /1.0/mountainAreas?include=multimediaDescriptions.copyrightOwner.
If the SERVER is unable to identify a relationship or does not support the inclusion of resources from a relationship, it MUST respond with 400 Bad Request.
A full example of request and response that makes usage of this feature can be found at the end of the section Message Body, where the CLIENT request for media object resources and for the inclusion of the resource available in the relationship copyrightOwner.
5. Endpoints
The AlpineBits® DestinationData API defines a set of endpoints for SERVERS to implement.
5.1. Base Endpoint
In order to retrieve the versions of AlpineBits® DestinationData implemented by the SERVER, the CLIENT MAY perform a GET request to the SERVER at the base endpoint /, as in the example below.
GET https://example.com/ HTTP/1.1
Accept: application/vnd.api+json
The SERVER MUST respond to requests to the base endpoint / with links to the implemented versions, as in example below.
In this response, the data field MUST be set to null.
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"links": {
"self": "https://example.com/",
"1.0": "https://example.com/1.0/"
},
"data": null
}
5.2. Version Endpoints
In order to retrieve the endpoints implemented by the SERVER, the CLIENT MAY perform a GET request to the SERVER at the endpoint of the desired version (e.g., /1.0/), as in the example below.
GET https://example.com/1.0/ HTTP/1.1
Accept: application/vnd.api+json
The SERVER MUST respond to requests to a version endpoint (e.g., /1.0/) with a message body as described below:
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"links": {
"self": "https://example.com/1.0/",
"events": "https://example.com/1.0/events",
"eventSeries": "https://example.com/1.0/eventSeries",
"lifts": "https://example.com/1.0/lifts",
"trails": "https://example.com/1.0/trails",
"snowparks": "https://example.com/1.0/snowparks",
"mountainAreas": "https://example.com/1.0/mountainAreas"
},
"data": null
}
In such responses, the data field MUST be set to null.
5.3. Resource Endpoints
To provide access to resources, a SERVER MUST listen to HTTPS requests in the following endpoints:
-
/1.0/agents -
/1.0/agents/:id -
/1.0/agents/:id/multimediaDescriptions -
/1.0/events -
/1.0/events/:id -
/1.0/events/:id/contributors -
/1.0/events/:id/multimediaDescriptions -
/1.0/events/:id/organizers -
/1.0/events/:id/publisher -
/1.0/events/:id/series -
/1.0/events/:id/sponsors -
/1.0/events/:id/subEvents -
/1.0/events/:id/venues -
/1.0/eventSeries -
/1.0/eventSeries/:id -
/1.0/eventSeries/:id/editions -
/1.0/eventSeries/:id/multimediaDescriptions -
/1.0/lifts -
/1.0/lifts/:id -
/1.0/lifts/:id/connections -
/1.0/lifts/:id/multimediaDescriptions -
/1.0/mediaObjects -
/1.0/mediaObjects/:id -
/1.0/mediaObjects/:id/copyrightOwner -
/1.0/mountainAreas -
/1.0/mountainAreas/:id -
/1.0/mountainAreas/:id/areaOwner -
/1.0/mountainAreas/:id/connections -
/1.0/mountainAreas/:id/lifts -
/1.0/mountainAreas/:id/multimediaDescriptions -
/1.0/mountainAreas/:id/snowparks -
/1.0/mountainAreas/:id/subAreas -
/1.0/mountainAreas/:id/trails -
/1.0/snowparks -
/1.0/snowparks/:id -
/1.0/snowparks/:id/connections -
/1.0/snowparks/:id/multimediaDescriptions -
/1.0/trails -
/1.0/trails/:id -
/1.0/trails/:id/connections -
/1.0/trails/:id/multimediaDescriptions -
/1.0/venues -
/1.0/venues/:id -
/1.0/venues/:id/multimediaDescriptions
The aforementioned endpoints are structured according to the following patterns:
-
/<version>/<resourceType> -
/<version>/<resourceType>/<resourceId> -
/<version>/<resourceType>/<resourceId>/<relationship>
Where:
-
<version>is a number code representing the version of the standard implemented. The current version of the standard is1.0. -
<resourceType>is a standard-defined resource type (e.g.,events,mountainAreas, andvenues). See Resources. -
<resourceId>: an ID that uniquely identifies a resource that instance of the<resourceType>. -
<relationship>: field name of a resource’s relationship. Allows access to a resource’s related resources, such as an event’s organizer.
Every SERVER MUST answer requests with actual data in at least one of the following endpoints:
/1.0/events, /1.0/mountainAreas, /1.0/lifts, /1.0/trails, /1.0/snowparks
Every SERVER MUST respond to requests to non-implemented endpoints with a 404 Not Found status code.