Fetching Data

For a given model instance, three methods are available for fetching resource data. All three methods expect a dictionary of options as the first argument. These options represent the request query string parameters.

Single Objects

To fetch a single resource object, call the Model.get_object() method, supplying the object id as the second argument:

>>> await UserModel().get_object({}, 1)
{
    'data': {
        'id': '1',
        'type': 'user',
        'attributes': {
            'email': 'dianagraham@fisher.com',
            'first': 'Robert',
            'last': 'Camacho',
            'createdOn': '2019-05-18T11:49:43Z',
            'status': 'active',
            'name': 'Robert Camacho'}
    }
}

The generated SQL query may look like this:

SELECT users.id AS id,
       users.email AS email,
       user_names.first AS first,
       user_names.last AS last,
       users.created_on AS created_on,
       users.status AS status,
       user_names.first || ' ' || public.user_names.last AS name
FROM public.users
JOIN public.user_names ON public.users.id = public.user_names.user_id
WHERE public.users.id = 1

If the resource object does not exist, a NotFound exception is raised:

>>> await UserModel().get_object({}, 1001)
Traceback (most recent call last):
  ...
jsonapi.exc.NotFound: [UserModel] object not found: user(1001)

Collections

To fetch a collection of objects, call the Model.get_collection() method:

>>> await UserModel().get_collection({})
{'data': [
    {
        'id': '1',
        'type': 'user',
        'attributes': {
            'email': 'dianagraham@fisher.com',
            'first': 'Robert',
            'last': 'Camacho',
            'createdOn': '2019-05-18T11:49:43Z',
            'status': 'active',
            'name': 'Robert Camacho'
        }
    },
    ...
]}

The generated SQL query may look like this:

SELECT users.id AS id,
       users.email AS email,
       user_names.first AS first,
       user_names.last AS last,
       users.created_on AS created_on,
       users.status AS status,
       user_names.first || ' ' || user_names.last AS name
FROM users
JOIN user_names ON users.id = user_names.user_id

Sparse Fieldsets

By default, only non-aggregate attribute fields are included in the response. Aggregate fields must be requested explicitly and relationship fields are included when related resources are requested using the include request parameter (see Inclusion of Related Resources).

To include specific attributes in the response, pass a comma separated list of field names using the appropriate fields[TYPE] option, where TYPE is the type of the resource model:

>>> await UserModel().get_object({
>>>     'fields[user]': 'name,email,created-on'
>>> }, 1)
{
    'data': {
        'id': '1',
        'type': 'user',
        'attributes': {
            'email': 'dianagraham@fisher.com',
            'createdOn': '2019-05-18T11:49:43Z',
            'name': 'Robert Camacho'}
    }
}

You can pass an option for different resource types included in the response. For an example, see this.

Sorting

To sort a collection of resource objects, pass on the names of fields to order by as a comma separated list using the sort request parameter. You can use “+” or “-” prefix to indicate the sorting direction for each filed: ascending or descending, respectively. No prefix implies ascending order.

For example, the following returns a collection of user objects sorted by the created-on field in descending order:

>>> await UserModel().get_collection({'sort': '-created-on'})

To sort the collection of followers of a specific user by last name first, and then by first name:

>>> await UserModel().get_related({
>>>     'sort': 'last,first'
>>> }, 1, 'followers')

Collections can be sorted by aggregate fields:

>>> await UserModel().get_collection({'sort': '-follower-count'})

Sorting by a relationship field, will sort by the related resource id field. The following calls have identical effect:

>>> await ArticleModel().get_collection({'sort': 'author'})
>>> await ArticleModel().get_collection({'sort': 'author.id'})

You can use dot notation to specify a different attribute. To sort articles by the author name:

>>> await ArticleModel().get_collection({'sort': 'author.name'})

Filtering

The filter[SPEC] option can be used to filter a collection of objects (or related objects).

In the simplest form, SPEC can be the name of any field in the model. This filter would include all objects where the field has a value equal to that supplied by the filter. The value is parsed based on the datatype of the field.

For example, the following returns a list of active user accounts:

>>> await UserModel().get_collection({
>>>     'filter[status]': 'active'
>>> })

By default, the filter will use the equality operator. To specify a different operator, you can append a colin and the operator symbol to the name of the field. For example, to return all accounts created since September of 2019:

>>> await UserModel().get_collection({
>>>     'filter[created-on:gt]': '2019-09'
>>> })

The supported operators (and their symbols) and value formats depends of the field’s datatype. For more details see :module:jsonapi.datatypes.

You can combine multiple filters, which will be AND-ed together:

>>> await UserModel().get_collection({
>>>     'filter[status:eq]': 'active',
>>>     'filter[created-on:gt]': '2019-09'
>>> })

Some datatypes accept comma-separated values. To fetch a specific list of users:

>>> await UserModel().get_collection({
>>>     'filter[id]': '1,2,3,6,8,9,10,11,12'
>>> })

Ranges are also supported. The following is equivalent to the example above:

>>> await UserModel().get_collection({'filter[id]': '<=3,6,>=8,12'})
>>> await UserModel().get_collection({'filter[id]': '<4,6,>7,<13'})

Ranges are also supported by the date and time datatypes. To return all accounts created in September of 2019:

>>> await UserModel().get_collection({
>>>    'filter[created-on]': '>2019-09,<2019-10'
>>> })

When filtering by a relationship fields, the objects are filtered by the id field related resource model. The following calls are equivalent:

>>> await ArticleModel().get_collection({'filter[author]': '1,2,3'})
>>> await ArticleModel().get_collection({'filter[author.id]': '1,2,3'})

You can also filter by an attribute of a related resource model:

>>> await ArticleModel().get_collection({'filter[author.status]': 'active'})

The reserved literals none, null, or na can be used to filter empty relationships. The values are case-insensitive. The following calls return articles with and without a publisher, respectively:

>>> await ArticleModel().get_collection({'filter[publisher:ne]': 'none'})
>>> await ArticleModel().get_collection({'filter[publisher:eq]': 'none'})