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 a collection of endpoints, replying with appropriate HTTP status codes and message bodies, as defined in this document.

A SERVER MAY implement other HTTP methods, such as POST, PATCH, and DELETE. If it does, it MUST comply with the JSON:API v1.0 in these methods.

It is RECOMMENDED that a SERVER documents its implementation of the AlpineBits® DestinationData standard through an OpenAPI-based documentation.

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 CLIENT MUST include the header Accept: application/vnd.api+json in the messages it sends to a SERVER for it to behave according to the rules described in this document.

GET /2021-04/events HTTP/1.1
Accept: application/vnd.api+json

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 the JSON:API media type and all instances of that media type are modified with media type parameters.

GET /2021-04/events HTTP/1.1
Accept: application/vnd.api+json;modified-parameter=value, application/vnd.api+json;foo=bar
HTTP/1.1 406 Not Acceptable
Content-Type: application/vnd.api+json

{
   "error": [{
      "status": "406",
      "title": "Not acceptable: all media types modified with parameters"
   }],
   ...
}

A SERVER MUST support authentication through the basic authentication method, but it MAY support additional methods (e.g., OAuth, JSON Web Token, and OpenID Connect) or even non-authenticated requests.

The following example presents the Authorization header of a request using basic authentication.

GET /2021-04/events HTTP/1.1
Accept: application/vnd.api+json
Authorization: Basic Y2hyaXM6c2VjcmV0

In this example, the value of Authorization contains the string john:secret encoded in base64 (Y2hyaXM6c2VjcmV0), as specified in the basic authentication method.

If a SERVER does not support non-authenticated requests, it MUST reply to such requests with the 401 Unauthorized status code.

HTTP/1.1 401 Unauthorized
Content-Type: application/vnd.api+json

{
   "error": [{
      "status": "401",
      "title": "Unauthenticated request"
   }],
   ...
}

A server MUST also respond with a 401 Unauthorized status code to requests using basic authentication but providing invalid credentials.

HTTP/1.1 401 Unauthorized
Content-Type: application/vnd.api+json

{
   "error": [{
      "status": "401",
      "title": "Invalid credentials"
   }],
   ...
}

2.2. Message Body

A request message using the HTTP GET method MUST NOT contain a body. Therefore, a SERVER MUST reply to such messages with a 400 Bad Request status code.

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
   "error": [{
      "status": "400",
      "title": "GET requests cannot include a body"
   }],
   ...
}

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, a SERVER MUST:

  • Encode this body in UTF-8; and

  • Include the following header in the message:
    Content-Type: application/vnd.api+json.

SERVERS MUST NOT add encoding parameters to the Content-Type header to enable compatibility with JSON:API v1.0 and its future releases.

SERVERS MUST include appropriate HTTP status codes in their response messages.

Response messages are classified into Success Messages and Error Messages, which are detailed in the following subsections.

3.1. Success Messages

A success message 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 JSON body with 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 a self link 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 the data field. 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": { ... },
}

Take, for instance, the request below for media object resources with inclusion of resources present in the copyrightOwner relationship field:

GET /2021-04/mediaObjects?include=copyrightOwner HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
Authorization: Basic Y2hyaXM6c2VjcmV0

A SERVER could generate, as a successful response, 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/2021-04/mediaObjects?page[number]=2",
    "prev": "https://example.com/2021-04/mediaObjects?page[number]=1",
    "first": "https://example.com/2021-04/mediaObjects?page[number]=1",
    "last": "https://example.com/2021-04/mediaObjects?page[number]=10",
    "self": "https://example.com/2021-04/mediaObjects"
  },
  "data": [
    {
      "type": "mediaObjects",
      "id": "1",
      "meta": {
        "dataProvider": null,
        "lastUpdate": null
      },
      "attributes": {
        "abstract": null,
        "contentType": "text/markdown",
        "description": null,
        "duration": null,
        "height": null,
        "license": null,
        "name": null,
        "shortName": null,
        "url": "https://example.com/description.md",
        "width": null
      },
      "relationships": {
        "categories": null,
        "copyrightOwner": {
          "data": {
            "type": "agents",
            "id": "1"
          },
          "links": {
            "related": "https://example.com/2021-04/mediaObjects/1/copyrgihtOwner/"
          }
        }
      },
      "links": {
        "self": "https://example.com/2021-04/mediaObjects/1"
      }
    }
  ],
  "included": [
    {
      "type": "agents",
      "id": "1",
      "meta": {
        "dataProvider": null,
        "lastUpdate": null
      },
      "attributes": {
        "abstract": null,
        "contactPoints": null,
        "dataProvider": null,
        "description": null,
        "lastUpdate": null,
        "name": {
          "eng": "Free University of Bozen-Bolzano"
        },
        "shortName": null,
        "url": null
      },
      "relationships": {
        "categories": null,
        "multimediaDescriptions": null
      },
      "links": {
        "self": "https://example.com/2021-04/agents/1"
      }
    }
  ]
}

asciidoc/examples/event.full.json

3.2. Error Messages

An error message 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 returned status code MUST 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

A SERVER MAY include a body in an error message.

If it does, the body MUST comply with the JSON:API v1.0 specification, which means an object structured as follows:

  • error: an array of error objects as defined in JSON:API v1.0. This field is mandatory and 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 MUST NOT have fields in addition to those listed above.

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."
        }
    ]
}

asciidoc/examples/error.example.json

3.3. Error Status Codes

A SERVER MUST reply with specific status codes in the following cases:

  • 400 Bad Request: when a CLIENT makes a request containing:

    • a method body

    • a query parameter not defined in this standard

    • a query parameter not supported by the SERVER

    • a query parameter with an incorrect value

    • conflicting query parameters

  • 401 Unauthorized: when a CLIENT makes a request:

    • using an authentication method, but the credentials fail to be validated by the SERVER

    • without an authentication method, but the SERVER does not accept such requests

  • 404 Not Found: when a CLIENT makes a request:

    • to an endpoint not defined in this standard

    • to a non-implemented endpoint

    • asking for a non-existing page number

  • 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 an Accept header containing a media type not supported by the SERVER or with encoding parameters in application/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 communication between CLIENTS and SERVERS more effective and efficient.

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 object according to what is defined in this standard.

A SERVER MUST use the endpoints it implements 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 /2021-04/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 CLIENTS to request a subset of a resource collection.

The response message containing such a subset is called a page.

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 /2021-04/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 into pages containing 10 events each (page[size]=10).

A SERVER that implements pagination MUST:

  • Be able to handle requests containing just a page[size] query parameter, just a page[number], or both.

  • Support pagination for GET requests in every base endpoint, such as /2021-04/events and /2021-04/mountainAreas.

  • Respond with the first page if no pagination parameters are sent in the request.

  • In paginated responses, 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. The next URL MUST be the same as last in 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. The prev URL MUST be the same as first in case the previous page is out of bounds. Non-nullable.

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "first": "https://example.com/2021-04/events?page[number]=1",
    "last": "https://example.com/2021-04/events?page[number]=100",
    "self": "https://example.com/2021-04/events?page[number]=2",
    "next": "https://example.com/2021-04/events?page[number]=3",
    "prev": "https://example.com/2021-04/events?page[number]=1"
  },
  ...
}
  • In paginated responses, 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 pages in the resource collection given the selected page size. Non-nullable.

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "meta": {
    "count": 1000,
    "pages": 100
  },
  ...
}
  • Respond a request for a non existing page with an error message whose status code is 404 Not Found.

GET /2021-04/events?page[number]=10000 HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json

A SERVER that implements pagination SHOULD:

  • Define a default page size.

  • Respond a request for a non existing page with an error message containing a body as follows:

GET /2021-04/events?page[number]=10000 HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
HTTP/1.1 404 Not Found
Content-Type: application/vnd.api+json

{
  "error": [
    {
      "status": "404",
      "title": "Page not found"
    }
  ],
  "links": {
     "self": "http://example.com/2021-04/events?page[number]=10000"
   }
}

4.3. Sorting

A SERVER SHOULD support requests to sort resource collections according to one or more criteria (sort fields), as defined in the JSON:API v1.0 specification.

A SERVER that implements this feature MUST:

  • Interpret the values of the sort query parameter as sort fields:

GET /2021-04/events?sort=name HTTP/1.1
Accept: application/vnd.api+json
  • Interpret a sort field to be ascending unless it is preceded by a minus (U+002D HYPHEN-MINUS, "-"), in which case it MUST interpret it to be descending:

GET /2021-04/events?sort=-name HTTP/1.1
Accept: application/vnd.api+json
  • Interpret a dot-separated (U+002E FULL-STOP, ".") sort field to be a request to sort by a relationship or a nested attribute:

GET /2021-04/events?sort=organizer.name HTTP/1.1
Accept: application/vnd.api+json
  • Respond with a 400 Bad Request if a request contains a sort field that is not supported by the SERVER:

GET /2021-04/events?sort=hello HTTP/1.1
Accept: application/vnd.api+json
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "https://example.com/2021-04/events?sort=hello",
  },
  "errors": [{
      "title": "Invalid query parameter value.",
      "status": 400
   }]
}

A SERVER that implements sorting SHOULD:

  • Adopt sort fields that correspond to resource attributes:

GET /2021-04/events?sort=name HTTP/1.1
Accept: application/vnd.api+json
  • Support sorting by combining multiple sort fields:

GET /2021-04/events?sort=name,startDate HTTP/1.1
Accept: application/vnd.api+json

A SERVER that implements sorting MAY:

  • Adopt sort fields that do not correspond to resource attributes and relationships.

GET /2021-04/events?sort=date HTTP/1.1
Accept: application/vnd.api+json

4.4. Random sorting

A SERVER MAY support requests to randomly sort resource collections according to a seed value.

A SERVER that implements this feature MUST:

  • Interpret the value of the random query parameter as the seed to be used to sort the resource collection:

GET /2021-04/events?random=5 HTTP/1.1
Accept: application/vnd.api+json
  • Always return resources in the same order for requests using a given seed value, provided everything else remains the same (e.g. the resource collection, the page size, and the page number)

  • Respond with a 400 Bad Request if a request combines a sort and a random query parameter:

GET /2021-04/events?random=5&sort=startDate HTTP/1.1
Accept: application/vnd.api+json
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "https://example.com/2021-04/events?random=5&sort=startDate",
  },
  "errors": [{
      "title": "Request contains conflicting queries.",
      "status": 400
   }]
}
  • Respond with a 400 Bad Request if a request includes a seed value that is not supported by the SERVER

GET /2021-04/events?random=hello HTTP/1.1
Accept: application/vnd.api+json
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "https://example.com/2021-04/events?random=hello",
  },
  "errors": [{
      "title": "Invalid query parameter value.",
      "status": 400
   }]
}

A SERVER that implements random sorting SHOULD:

  • Allow a CLIENT to combine random with every other query parameter defined in this document, except for sort:

GET /2021-04/events?random=12&fields[events]=name,startDate&page[size]=30&page[number]=2 HTTP/1.1
Accept: application/vnd.api+json

4.5. Filtering

A SERVER SHOULD support filtering over its resources.

This standard specifies two strategies for filtering, label-specific filters and simple generic filters:

  • Label-specific filter: the SERVER defines the name of each supported filter, its semantics, and the values it may receive. Label-specifics filters MUST be defined as filter[FILTER-NAME]=VALUES, where VALUES may be a list of comma-separated values.

    For instance, a filter for resources updated after 01/01/2021 could be defined as follows:

GET /2021-04/events?filter[lastUpdate]=2021-01-01 HTTP/1.1
Accept: application/vnd.api+json
  • Simple generic filter: this standard defines a list of generic filter operands, their semantics, and the values it may receive. These filters are then requested over resources' fields following the pattern filter[FIELD][OPERAND]=VALUES.

    For instance, a request to retrieve events starting after 01/01/2021 is defined as follows.

GET /2021-04/events?filter[startDate][gt]=2021-01-01 HTTP/1.1
Accept: application/vnd.api+json

A SERVER is RECOMMENDED to support filtering over the following data:

  • Last update

  • Language

  • Categories

  • Date (events)

  • Publisher (events)

  • Location (geolocation or address based)

  • Length (ski slopes, snowparks)

  • Opening schedule - open at (places open on a certain date)

  • Difficulty (ski slopes, snowparks)

  • Snow conditions (mountain areas, snowparks)

  • Area owner (mountain areas)

A SERVER MAY support multiple filters in a single request.

A SERVER MUST reply to requests with non-supported filters, field names, or values with 400 Bad Request status code:

GET /2021-04/events?filter[foo]=bar HTTP/1.1
Accept: application/vnd.api+json
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "https://example.com/2021-04/events?filter[foo]=bar",
  },
  "errors": [{
      "title": "Invalid query parameter value.",
      "status": 400
   }]
}

A SERVER MAY support custom filters, i.e., those that are cannot be expressed as simple generic filters, as label-specific filters: For example, a filter retrieves events "active" in between two dates:

GET /2021-04/events?filter[between]=2021-03-01,2021-03-10 HTTP/1.1
Accept: application/vnd.api+json

A SERVER SHOULD prefer simple generic filters over label specific filters.

A SERVER MAY support simple generic filters over nested fields. For example, a filter over the countries in venues' addresses:

GET /2021-04/venues?filter[address.country][eq]=IT HTTP/1.1
Accept: application/vnd.api+json

The standard defines the following list of operands for simple generic filters:

  • exists: filters resources that according to whether or not the field has values (i.e., it is not null). Accepts as argument a single true or false value.
    For example, filter event resources that have multimedia descriptions:

GET /2021-04/events?filter[multimediaDescriptions][exists]=true HTTP/1.1
Accept: application/vnd.api+json
  • eq: filters resources that have the field assigned to a specific value. Accepts as argument a single boolean, number, or string value.
    For example, filter venue resources whose address has a specific country value:

GET /2021-04/venues?filter[address.country][eq]=IT HTTP/1.1
Accept: application/vnd.api+json
  • neq: filters resources that have the field not assigned to a specific value. Accepts as argument a single boolean, number, or string value.
    For example, filter snowpark resources whose difficulty level is not "expert":

GET /2021-04/snowparks?filter[difficulty][neq]=expert HTTP/1.1
Accept: application/vnd.api+json
  • in: filters resources that have the field assigned to values within a desired list. Accepts a list of number or string arguments.
    For example, filter snowpark resources whose difficulty is within the list [ "beginner", "intermediate" ].

GET /2021-04/snowparks?filter[difficulty][in]=beginner,intermediate HTTP/1.1
Accept: application/vnd.api+json
  • nin: filters resources that have the field not assigned to values within a desired list. Accepts a list of number or string arguments.
    For example, filter snowpark resources whose difficulty is not within the list [ "advanced", "expert" ].

GET /2021-04/snowparks?filter[difficulty][nin]=advanced,expert HTTP/1.1
Accept: application/vnd.api+json
  • any: filters resources that have some of the field’s values within a desired list. Accepts a list of number or string arguments.
    For example, filter event resources whose categories include some of the values in the list [ "schema:MusicEvent", "schema:SportsEvent" ].

GET /2021-04/events?filter[categories][any]=schema:MusicEvent,schema:SportsEvent HTTP/1.1
Accept: application/vnd.api+json
  • all: filters resources that have all of the field’s values within a desired list. Accepts a list of number or string arguments.
    For example, filter event resources whose categories include some of the values in the list [ "schema:Festival", "schema:MusicEvent" ].

GET /2021-04/events?filter[categories][any]=schema:Festival,schema:MusicEvent HTTP/1.1
Accept: application/vnd.api+json
  • gt: filters resources that have the field assigned to a value greater than the desired one. Accepts as argument a single number or string.
    For example, retrieve agent resources that have their last update greater than a certain date-time:

GET /2021-04/agents?filter[lastUpdate][gt]=2021-04-01T00:00:00+0000 HTTP/1.1
Accept: application/vnd.api+json
  • gte: filters resources that have the field assigned to a value greater than or equal to the desired one. Accepts as argument a single number or string.
    For example, retrieve agent resources that have their last update greater than or equal to a certain date-time:

GET /2021-04/agents?filter[lastUpdate][gte]=2021-04-01T00:00:00+0000 HTTP/1.1
Accept: application/vnd.api+json
  • lt: filters resources that have the field assigned to a value lower than the desired one. Accepts as argument a single number or string.
    For example, retrieve ski slope resources that have their length lower than a certain value:

GET /2021-04/skiSlopes?filter[length][lt]=5000 HTTP/1.1
Accept: application/vnd.api+json
  • lte: filters resources that have the field assigned to a value lower than or equal to the desired one. Accepts as argument a single number or string.
    For example, retrieve ski slope resources that have their length lower than or equal to a certain value:

GET /2021-04/skiSlopes?filter[length][lte]=5000 HTTP/1.1
Accept: application/vnd.api+json
  • near: filters resources located within a certain distance to a pair of coordinates. Accepts a triple of number arguments representing a coordinate’s longitude and latitude, and a distance in meters (i.e., LONGITUDE,LATITUDE,DISTANCE).
    For example, retrieve lift resources whose geometries are within 10000 meters geo-located pair of longitude and latitude (11.891472,46.92275):

GET /2021-04/lifts?filter[geometries][near]=11.891472,46.92275,10000 HTTP/1.1
Accept: application/vnd.api+json
  • intersects: filters resources whose geo-location data intersects a desired area. Accepts as argument a single string representing a GeoJSON object of type "Polygon" (see datatypes.adoc#anchor-geometry).
    For example, filter mountain areas whose geometry intersects a specific area (e.g., the area surrounding a mountain).

GET /2021-04/mountainAreas?filter[geometries][intersects]={"type":"Polygon","coordinates": [[11.3490,46.4976],[11.3508,46.4975],[11.3510,46.4989],[11.3492,46.4990]]]} HTTP/1.1
Accept: application/vnd.api+json
  • within: filters resources whose geo-location data is within a desired area. Accepts as argument a single string representing a GeoJSON object of type "Polygon" (see datatypes.adoc#anchor-geometry).
    For example, filter venues whose geometry is within a specific area.

GET /2021-04/venues?filter[geometries][within]={"type":"Polygon","coordinates": [[11.3490,46.4976],[11.3508,46.4975],[11.3510,46.4989],[11.3492,46.4990]]]} HTTP/1.1
Accept: application/vnd.api+json
  • starts: filters resources whose text field starts with a desired substring. Accepts as argument a single string.
    For example, filter media object resources whose content type string start with a certain substring:

GET /2021-04/mediaObjects?filter[contentType][starts]=video HTTP/1.1
Accept: application/vnd.api+json
  • ends: filters resources whose text field ends with a desired substring. Accepts as argument a single string.
    For example, filter media object resources whose content type string ends with a certain substring:

GET /2021-04/mediaObjects?filter[contentType][end]=png HTTP/1.1
Accept: application/vnd.api+json
  • regex: filters resources whose text field passes a desired regular expression. Accepts as argument a single string representing a regular expression.
    For example, filter media object resources whose content type passes a certain regular expression:

GET /2021-04/mediaObjects?filter[contentType][regex]=^(audio|image|video) HTTP/1.1
Accept: application/vnd.api+json

4.6. Searching

A SERVER SHOULD support text search over its resources.

A SERVER that implements this feature MUST:

  • Interpret the value of a search[FIELD] query parameter as the string to be used to search for resources, while the value between square brackets refers to the resources' field that should be considered in the search:

GET /2021-04/events?search[name]=bolzano HTTP/1.1
Accept: application/vnd.api+json
  • Respond with a 400 Bad Request if a request searches for a query string on a field that does not exist on the resource types returned by the queried endpoint.

GET /2021-04/events?search[license]=bolzano HTTP/1.1
Accept: application/vnd.api+json
HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "https://example.com/2021-04/events?search[license]=bolzano",
  },
  "errors": [{
      "title": "Invalid query parameter value.",
      "status": 400
   }]
}

A SERVER that implements searching SHOULD:

  • Support searching at least over the name and description attributes, which are defined for all resource types:

GET /2021-04/events?search[name]=bolzano HTTP/1.1
Accept: application/vnd.api+json
  • Allow CLIENTS to combine a search query parameter with any other query parameter defined in this standard:

GET /2021-04/events?search[name]=bolzano&page[size]=20&fields[events]=name,startDate&sort=-startDate HTTP/1.1
Accept: application/vnd.api+json

A SERVER that implements searching MAY:

  • Support searching over all fields of a resource type by accepting a search query parameter that is not followed by square brackets:

GET /2021-04/events?search=bolzano HTTP/1.1
Accept: application/vnd.api+json
  • Choose how its search feature behaves. For instance, a SERVER MAY return resources whose fields match or contain the search string, or whose fields contain a substring that is similar to the search string.

4.7. Sparse Fieldsets

A SERVER MAY support requests to return only specific fields that characterize a resource on a per-type basis, as defined in the JSON:API v1.0 specification

This feature applies both to endpoints that return collections of resources, e.g. /2021-04/events, and those that return individual resources, e.g. /2021-04/events/123.

A SERVER that implements this feature MUST:

  • Interpret the comma-separated (U+002C COMMA, ",") values of field[TYPE] query parameters as the selected fields (attributes or relationships) to be returned for a given resource type, which in turn is identified by the value between square brackets:

GET /2021-04/agents?fields[agents]=name,contactPoints HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
   "links": {
      "self": "https://example.com/2021-04/agents?fields[agents]=name,contactPoints",
   },
   "data": [{
      "type": "agents",
      "id": "1",
      "meta": { ... },
      "attributes": {
         "name": {
            "eng": "Free University of Bozen-Bolzano"
         },
         "contactPoints": { ... },
      },
      "relationships": null,
      "links": { ... }
   }]
}
  • Be able to process one field[TYPE] query parameter per resource type:

GET /2021-04/events?fields[events]=name,startDate&fields[agents]=name,contactPoints&include=organizers HTTP/1.1
Host: https://example.com
Accept: application/vnd.api+json
  • NOT include additional fields in resource objects if a CLIENT requests a restricted field set (using fields[]) for the respective resource types.

  • Send all fields for resource objects if a CLIENT does not select a restricted field set (using fields[]) for the respective resource types.

  • Respond with a 400 Bad Request status code a request that selects fields that do not exist for a resource type.

GET /2021-04/events?fields[events]=price HTTP/1.1
Accept: application/vnd.api+json
  • Respond with a 400 Bad Request status code a request that submits multiple field[] parameters for one resource type.

GET /2021-04/events?fields[events]=name&fields[events]=name,startDate HTTP/1.1
Accept: application/vnd.api+json
  • Respond with a 400 Bad Request status code a request that selects fields on resource types that are not returned in the queried endpoint.

GET /2021-04/events?fields[lifts]=name HTTP/1.1
Accept: application/vnd.api+json

HTTP/1.1 400 Bad Request
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "https://example.com/2021-04/events?fields[lifts]=name",
  },
  "errors": [{
      "title": "Query parameter does not have valid values.",
      "status": 400
   }]
}

4.8. 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 returned in the response.

An example of a request asking for related resources is shown below:

GET /2021-04/events?include=organizers HTTP/1.1
Accept: application/vnd.api+json

It is RECOMMENDED that SERVERS support the inclusion of related resources.

In successful messages, a 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 /2021-04/events?include=organizers,sponsors and /2021-04/mountainAreas?include=skiSlopes,lifts,snowparks.

To request resources related to other resources, a dot-separated path for each relationship name can be specified, as in /2021-04/events?include=organizers.multimediaDescriptions and /2021-04/mountainAreas?include=multimediaDescriptions.copyrightOwner.

If a 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 complete example of a request and a response using this feature can be found at the end of the section Message Body, where a CLIENT requests media objects, while also including the agent in the copyrightOwner relationship.

5. Endpoints

The AlpineBits® DestinationData API defines a set of endpoints for SERVERS to implement.

5.1. Base Endpoint

To retrieve the versions of AlpineBits® DestinationData implemented by a SERVER, a CLIENT MAY send a GET request to that SERVER’s base endpoint /, as in the example below.

GET https://example.com/ HTTP/1.1
Accept: application/vnd.api+json

A SERVER MUST respond to requests to the base endpoint / with links to the implemented versions, as in the 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/",
    "2020-04": "https://example.com/2020-04/",
    "2021-04": "https://example.com/2021-04/"
  },
  "data": null
}

5.2. Version Endpoints

To retrieve the endpoints implemented by a SERVER, a CLIENT MAY perform a GET request on the desired version’s endpoint (e.g., /2021-04/), as in the example below.

GET https://example.com/2021-04/ HTTP/1.1
Accept: application/vnd.api+json

A SERVER that receives such a request MUST reply it with a response containing a message body structured as follows:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "https://example.com/2021-04/",
    "events": "https://example.com/2021-04/events",
    "eventSeries": "https://example.com/2021-04/eventSeries",
    "lifts": "https://example.com/2021-04/lifts",
    "skiSlopes": "https://example.com/2021-04/skiSlopes",
    "snowparks": "https://example.com/2021-04/snowparks",
    "mountainAreas": "https://example.com/2021-04/mountainAreas"
  },
  "data": null
}

In such responses, the data field MUST be set to null.

SERVERS MUST adopt an endpoint version that is the same as the standard version they implement.

5.3. Resource Endpoints

Resource 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 adopted version of the standard. Its possible values are:

    • 2020-04: first release

    • 2021-04: current release

  • <resourceType> is a standard-defined resource type (e.g., events, mountainAreas, and venues). See Resources.

  • <resourceId>: an ID that uniquely identifies a resource that is an 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.

To provide access to resources, a SERVER MUST listen to HTTPS requests in the following endpoints:

  • /2021-04/agents

  • /2021-04/agents/:id

  • /2021-04/agents/:id/categories

  • /2021-04/agents/:id/multimediaDescriptions

  • /2021-04/categories

  • /2021-04/categories/:id

  • /2021-04/categories/:id/children

  • /2021-04/categories/:id/multimediaDescriptions

  • /2021-04/categories/:id/parents

  • /2021-04/events

  • /2021-04/events/:id

  • /2021-04/events/:id/categories

  • /2021-04/events/:id/contributors

  • /2021-04/events/:id/multimediaDescriptions

  • /2021-04/events/:id/organizers

  • /2021-04/events/:id/publisher

  • /2021-04/events/:id/series

  • /2021-04/events/:id/sponsors

  • /2021-04/events/:id/subEvents

  • /2021-04/events/:id/venues

  • /2021-04/eventSeries

  • /2021-04/eventSeries/:id

  • /2021-04/eventSeries/:id/categories

  • /2021-04/eventSeries/:id/editions

  • /2021-04/eventSeries/:id/multimediaDescriptions

  • /2021-04/features

  • /2021-04/features/:id

  • /2021-04/features/:id/children

  • /2021-04/features/:id/multimediaDescriptions

  • /2021-04/features/:id/parents

  • /2021-04/lifts

  • /2021-04/lifts/:id

  • /2021-04/lifts/:id/categories

  • /2021-04/lifts/:id/connections

  • /2021-04/lifts/:id/multimediaDescriptions

  • /2021-04/mediaObjects

  • /2021-04/mediaObjects/:id

  • /2021-04/mediaObjects/:id/categories

  • /2021-04/mediaObjects/:id/copyrightOwner

  • /2021-04/mountainAreas

  • /2021-04/mountainAreas/:id

  • /2021-04/mountainAreas/:id/areaOwner

  • /2021-04/mountainAreas/:id/categories

  • /2021-04/mountainAreas/:id/connections

  • /2021-04/mountainAreas/:id/lifts

  • /2021-04/mountainAreas/:id/multimediaDescriptions

  • /2021-04/mountainAreas/:id/skiSlopes

  • /2021-04/mountainAreas/:id/snowparks

  • /2021-04/mountainAreas/:id/subAreas

  • /2021-04/skiSlopes

  • /2021-04/skiSlopes/:id

  • /2021-04/skiSlopes/:id/categories

  • /2021-04/skiSlopes/:id/connections

  • /2021-04/skiSlopes/:id/multimediaDescriptions

  • /2021-04/snowparks

  • /2021-04/snowparks/:id

  • /2021-04/snowparks/:id/categories

  • /2021-04/snowparks/:id/connections

  • /2021-04/snowparks/:id/features

  • /2021-04/snowparks/:id/multimediaDescriptions

  • /2021-04/venues

  • /2021-04/venues/:id

  • /2021-04/venues/:id/categories

  • /2021-04/venues/:id/multimediaDescriptions

A SERVER MUST answer requests with actual data in at least one of the following endpoints:

  • /2021-04/events

  • /2021-04/mountainAreas

  • /2021-04/lifts

  • /2021-04/skiSlopes

  • /2021-04/snowparks

A SERVER MUST respond to requests to non-implemented endpoints with a 404 Not Found status code.