======================================================
Filtering, pagination, ordering, and excluding fields
======================================================

The API allows results to be paginated, filtered, and ordered, and for
fields to be excluded from the result.

Pagination
-----------

By default, the API returns all the resources in the result set. This
can be a large number of resources if, for example, the request is for
all the bonds in the database. To limit the size of the response,
results can be paginated. Pagination is only applicable to list
resources, such as the bond list resource. It is not applicable to
individual object resources.

Responses are paginated by supplying the following request parameters:

-  ``page_size``. An integer specifying the number of objects in the
   response.
-  ``page``. The page offset starting at 1.

For example, to fetch bond records 26-50, request this URI:

::

    /api/v4/bonds/?page=2&page_size=25

Specifying pagination options changes the structure of the response.
With no pagination options, the response is simply a list of the result
objects. For example, the regular bond list in JSON would be something
like:

::

    [
        { ... bond object ... },
        { ... bond object ... },
        { ... bond object ... }
    ]

However, additional fields are returned when pagination options are
provided. This helps to simplify client software by supplying URIs and
other information directly from the server, as called for by REST
patterns. For example, paginated bond list in JSON would be:

::

    {
        "count": 42,
        "next": "https://bondingadmin.example.com/api/v4/bonds/?page=3&page_size=3",
        "previous": "https://bondingadmin.example.com/api/v4/bonds/?page_size=3",
        "results": [
            { ... bond object ... },
            { ... bond object ... },
            { ... bond object ... }
        ]
    }

The extra fields are:

-  ``count``. The total number of objects in the result set.
-  ``next``. The URL of the next page of results.
-  ``previous``. The URL of the previous page of results.
-  ``results``. The list of result objects.

Filtering
----------

Result sets can be filtered against certain fields. To filter on a
field, simply add the field as a request argument. For example, to fetch
bonds using the IDMPQ packet distribution algorithm, use this URI:

::

    /api/v4/bonds/?packet_distribution=idmpq

Multiple filter fields can be separated by ampersands (&).

One special filtering argument is ``search``. Some resources support the
``search`` parameter to filter on multiple fields at once. For example,
to search for bonds that have the term "foo" in either the note field,
bonder name, or bonder version, fetch this URI:

::

    /api/v4/bonds/?search=foo

Not all fields on a resource are available for filtering or searching.
If you would like to filter on a field that isn't currently available
for filtering or search, please `contact technical
support <../../spaces/technical-support.html>`__.

Ordering
---------

To retrieve a result set ordered by a field or set of fields, add an
``ordering`` parameter to the request. For example, to list bonds by
current download rate, with highest throughput bonds last, fetch this
URI:

::

    /api/v4/bonds/?ordering=download_rate,

To sort by multiple fields, separate the field names with a comma:

::

    ?ordering=field1,field2

By default, smallest values are listed first. To perform a descending
sort instead of an ascending sort, add a dash to the field name:

::

    ?ordering=-field1,field2

Excluding fields
-----------------

Fields can be excluded from a response in order to make it return
faster, because the server needs to collect less information when
creating the response, or to reduce the size of the response to reduce
network usage.

To exclude one or more fields from the response, add one or more
``exclude_fields`` parameters to the URI query string. For example, to
exclude the progress_results field from a speed test response, use the
following URI:

``/api/v4/bonds/1/speedtests/?exclude_fields=progress_results``

To exclude multiple fields, add multiple exclude_fields parameters:

``?exclude_fields=progress_results&exclude_fields=actual_length``
