Skip to content

Fetching data

# Fetching Data

Data, including resources and relationships, can be fetched by sending a GET request to an endpoint.

Responses can be further refined with the optional features described below.

# Fetching Resources

A server MUST support fetching resource data for every URL provided as:

  • a self link as part of the top-level links object
  • a self link as part of a resource-level links object
  • a related link as part of a relationship-level links object

For example, the following request fetches a collection of orders:

GET /orders HTTP/1.1
Accept: application/vnd.api+json

The following request fetches an order:

GET /orders/1 HTTP/1.1
Accept: application/vnd.api+json

And the following request fetches an order's retailer:

GET /orders/1/retailer HTTP/1.1
Accept: application/vnd.api+json

# Responses

# 200 OK

A server MUST respond to a successful request to fetch an individual resource or resource collection with a 200 OK response.

A server MUST respond to a successful request to fetch a resource collection with an array of resource objects or an empty array ([]) as the response document's primary data.

For example, a GET request to a collection of orders could return:

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

{
  "links": {
    "self": "http://example.com/orders"
  },
  "data": [{
    "type": "orders",
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "attributes": {
      "billingName": "Mose Schrute"
    }
  }, {
    "type": "orders",
    "id": "222e4567-e89b-12d3-a456-426614174000",
    "attributes": {
      "billingName": "Dwight Schrute"
    }
  }]
}

A similar response representing an empty collection would be:

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

{
  "links": {
    "self": "http://example.com/orders"
  },
  "data": []
}

A server MUST respond to a successful request to fetch an individual resource with a resource object or null provided as the response document's primary data.

null is only an appropriate response when the requested URL is one that might correspond to a single resource, but doesn't currently.

Note: Consider, for example, a request to fetch a to-one related resource link. This request would respond with null when the relationship is empty (such that the link is corresponding to no resources) but with the single related resource's resource object otherwise.

For example, a GET request to an individual order could return:

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

{
  "links": {
    "self": "http://example.com/orders/1"
  },
  "data": {
    "type": "orders",
    "id": "1",
    "attributes": {
      "title": "JSON:API paints my bikeshed!"
    },
    "relationships": {
      "retailer": {
        "links": {
          "related": "http://example.com/orders/1/retailer"
        }
      }
    }
  }
}

If the above order's retailer is missing, then a GET request to that related resource would return:

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

{
  "links": {
    "self": "http://example.com/orders/1/retailer"
  },
  "data": null
}
# 404 Not Found

A server MUST respond with 404 Not Found when processing a request to fetch a single resource that does not exist, except when the request warrants a 200 OK response with null as the primary data (as described above).

# Other Responses

A server MAY respond with other HTTP status codes.

A server MAY include error details with error responses.

A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics.

# Fetching Relationships

A server MUST support fetching relationship data for every relationship URL provided as a self link as part of a relationship's links object.

For example, the following request fetches data about an order's comments:

GET /orders/1/relationships/comments HTTP/1.1
Accept: application/vnd.api+json

And the following request fetches data about an order's retailer:

GET /orders/1/relationships/retailer HTTP/1.1
Accept: application/vnd.api+json

# Responses

# 200 OK

A server MUST respond to a successful request to fetch a relationship with a 200 OK response.

The primary data in the response document MUST match the appropriate value for resource linkage, as described above for relationship objects.

The top-level links object MAY contain self and related links, as described above for relationship objects.

For example, a GET request to a URL from a to-one relationship link could return:

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

{
  "links": {
    "self": "/orders/1/relationships/retailer",
    "related": "/orders/1/retailer"
  },
  "data": {
    "type": "people",
    "id": "12"
  }
}

If the above relationship is empty, then a GET request to the same URL would return:

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

{
  "links": {
    "self": "/orders/1/relationships/retailer",
    "related": "/orders/1/retailer"
  },
  "data": null
}

A GET request to a URL from a to-many relationship link could return:

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

{
  "links": {
    "self": "/orders/1/relationships/tags",
    "related": "/orders/1/tags"
  },
  "data": [
    { "type": "tags", "id": "2" },
    { "type": "tags", "id": "3" }
  ]
}

If the above relationship is empty, then a GET request to the same URL would return:

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

{
  "links": {
    "self": "/orders/1/relationships/tags",
    "related": "/orders/1/tags"
  },
  "data": []
}
# 404 Not Found

A server MUST return 404 Not Found when processing a request to fetch a relationship link URL that does not exist.

Note: This can happen when the parent resource of the relationship does not exist. For example, when /orders/1 does not exist, request to /orders/1/relationships/tags returns 404 Not Found.

If a relationship link URL exists but the relationship is empty, then 200 OK MUST be returned, as described above.

# Other Responses

A server MAY respond with other HTTP status codes.

A server MAY include error details with error responses.

A server MUST prepare responses, and a client MUST interpret responses, in accordance with HTTP semantics.

An endpoint MAY return resources related to the primary data by default.

An endpoint MAY also support an include request parameter to allow the client to customize which related resources should be returned.

If an endpoint does not support the include parameter, it MUST respond with 400 Bad Request to any requests that include it.

If an endpoint supports the include parameter and a client supplies it, the server MUST NOT include unrequested resource objects in the included section of the compound document.

The value of the include parameter MUST be a comma-separated (U+002C COMMA, ",") list of relationship paths. A relationship path is a dot-separated (U+002E FULL-STOP, ".") list of relationship names.

If a server is unable to identify a relationship path or does not support inclusion of resources from a path, it MUST respond with 400 Bad Request.

Note: For example, a relationship path could be comments.retailer, where comments is a relationship listed under a orders resource object, and retailer is a relationship listed under a comments resource object.

For instance, comments could be requested with an order:

GET /orders/1?include=comments HTTP/1.1
Accept: application/vnd.api+json

In order to request resources related to other resources, a dot-separated path for each relationship name can be specified:

GET /orders/1?include=comments.retailer HTTP/1.1
Accept: application/vnd.api+json

Note: Because compound documents require full linkage (except when relationship linkage is excluded by sparse fieldsets), intermediate resources in a multi-part path must be returned along with the leaf nodes. For example, a response to a request for comments.retailer should include comments as well as the retailer of each of those comments.

Note: A server may choose to expose a deeply nested relationship such as comments.retailer as a direct relationship with an alias such as comment-retailers. This would allow a client to request /orders/1?include=comment-retailers instead of /orders/1?include=comments.retailer. By abstracting the nested relationship with an alias, the server can still provide full linkage in compound documents without including potentially unwanted intermediate resources.

Multiple related resources can be requested in a comma-separated list:

GET /orders/1?include=comments.retailer,ratings HTTP/1.1
Accept: application/vnd.api+json

Furthermore, related resources can be requested from a relationship endpoint:

GET /orders/1/relationships/comments?include=comments.retailer HTTP/1.1
Accept: application/vnd.api+json

In this case, the primary data would be a collection of resource identifier objects that represent linkage to comments for an order, while the full comments and comment retailers would be returned as included data.

Note: This section applies to any endpoint that responds with primary data, regardless of the request type. For instance, a server could support the inclusion of related resources along with a POST request to create a resource or relationship.

# Sparse Fieldsets

A client MAY request that an endpoint return only specific fields in the response on a per-type basis by including a fields[TYPE] parameter.

The value of the fields parameter MUST be a comma-separated (U+002C COMMA, ",") list that refers to the name(s) of the fields to be returned. An empty value indicates that no fields should be returned.

If a client requests a restricted set of fields for a given resource type, an endpoint MUST NOT include additional fields in resource objects of that type in its response.

If a client does not specify the set of fields for a given resource type, the server MAY send all fields, a subset of fields, or no fields for that resource type.

GET /orders?include=retailer&fields[orders]=title,body&fields[people]=name HTTP/1.1
Accept: application/vnd.api+json

Note: The above example URI shows unencoded [ and ] characters simply for readability. In practice, these characters must be percent-encoded, per the requirements in RFC 3986.

Note: This section applies to any endpoint that responds with resources as primary or included data, regardless of the request type. For instance, a server could support sparse fieldsets along with a POST request to create a resource.

# Sorting

A server MAY choose to support requests to sort resource collections according to one or more criteria ("sort fields").

Note: Although recommended, sort fields do not necessarily need to correspond to resource attribute and association names.

Note: It is recommended that dot-separated (U+002E FULL-STOP, ".") sort fields be used to request sorting based upon relationship attributes. For example, a sort field of retailer.name could be used to request that the primary data be sorted based upon the name attribute of the retailer relationship.

An endpoint MAY support requests to sort the primary data with a sort query parameter. The value for sort MUST represent sort fields.

GET /people?sort=age HTTP/1.1
Accept: application/vnd.api+json

An endpoint MAY support multiple sort fields by allowing comma-separated (U+002C COMMA, ",") sort fields. Sort fields SHOULD be applied in the order specified.

GET /people?sort=age,name HTTP/1.1
Accept: application/vnd.api+json

The sort order for each sort field MUST be ascending unless it is prefixed with a minus (U+002D HYPHEN-MINUS, "-"), in which case it MUST be descending.

GET /orders?sort=-created,title HTTP/1.1
Accept: application/vnd.api+json

The above example should return the newest orders first. Any orders created on the same date will then be sorted by their title in ascending alphabetical order.

If the server does not support sorting as specified in the query parameter sort, it MUST return 400 Bad Request.

If sorting is supported by the server and requested by the client via query parameter sort, the server MUST return elements of the top-level data array of the response ordered according to the criteria specified. The server MAY apply default sorting rules to top-level data if request parameter sort is not specified.

Note: This section applies to any endpoint that responds with a resource collection as primary data, regardless of the request type.

# Pagination

A server MAY choose to limit the number of resources returned in a response to a subset ("page") of the whole set available. Ankorstore uses cursor based pagination.

A server MUST provide links to traverse a paginated data set ("pagination links").

These links MUST appear in the links object that corresponds to a collection in the top-level links object.

The following keys MUST be used for pagination links:

  • first: the first page of data
  • prev: the previous page of data
  • next: the next page of data

Keys MUST either be omitted or have a null value to indicate that a particular link is unavailable.

As an example:

{
  "links": {
    "first": "https://www.ankorstore.com/api/v1/orders?include=&page%5Blimit%5D=15",
    "next": "https://www.ankorstore.com/api/v1/orders?include=&page%5Bafter%5D=1189606a-139e-4b4e-917c-b0c992498bad&page%5Blimit%5D=15",
    "prev": "https://www.ankorstore.com/api/v1/orders?include=&page%5Bbefore%5D=e04e17bb-9e70-4ecd-a8f5-4417d45b872c&page%5Blimit%5D=15"
  }
}

Note: The example query parameters above use unencoded [ and ] characters

The page query parameter is reserved for pagination. Servers and clients MUST use this key for pagination operations.

Our implementation uses cursor-based pagination via the "after" and "before" page parameters.

Both parameters take an existing resource ID value (see below) and return resources in a fixed order.

By default this fixed order is reverse chronological order (i.e. most recent first, oldest last).

The "before" parameter returns resources listed before the named resource. The "after" parameter returns resources listed after the named resource.

If both parameters are provided, only "before"is used.

If neither parameter is provided, the first page of results will be returned.

Parameter Description
after A cursor for use in pagination. after is a resource ID that defines your place in the list. For instance, if you make a paged request and receive 100 resources, ending with resource with id foo, your subsequent call can include page[after]=foo in order to fetch the next page of the list.
before A cursor for use in pagination. before is a resource ID that defines your place in the list. For instance, if you make a paged request and receive 100 resources, starting with resource with id bar your subsequent call can include page[before]=bar in order to fetch the previous page of the list.
limit A limit on the number of resources to be returned, i.e. the per-page amount.

Pagination information

If pagination is implemented by the server, the server SHOULD provide pagination details in the top-level meta object.

Pagination meta SHOULD contain the page object which must use these fields:

  • from: the identifier of the first resource in the set
  • to: the identifier of the last resource in the set
  • hasMore: a boolean that will inform the client on whether there are more pages
  • perPage: the maximum number of resources per page in the response

As an example:

{
  "meta": {
    "page": {
      "from": "63e9bacd-0288-4cf1-81ab-b34270c7f68a",
      "to": "747a1dcd-decc-4f8d-a9a9-61ff4d33d92e",
      "hasMore": true,
      "perPage": 15
    }
  }
}

# Sorting and Filtering

The filter query parameter is reserved for filtering data. Servers and clients SHOULD use this key for filtering operations.

An endpoint that supports filters requires each listed filter to be wrapped in a filter object.

E.g you may wish to only retrieve new orders:

?filter[status]=ankor_confirmed

You may also chain filters as well:

?filter[status]=ankor_confirmed&filter[retailerId]=1189606a-572e-4b4e-88da-b0c992498bad

Also a filter does not necessarily requires a value:

?filter[active]

And more complex filters MUST be implemented using array parameters like so:

?filter[foo][arg1]=bar&filter[foo][arg2]=buzz

What filters can be used?

The supported filters will be listed against each endpoint in the API documentation.