Follow @bissell
Michael's blog


The API Contract
Default Formats
General API Management
Error Standards
Response Codes
Collections
Filters
Cherry Picking
Conveniences
Change Logs

Filters

All collections should be filterable using the same filter schema

All fields should be searchable
Lists of results should be sortable

String Comparisons

It is expected that any field in an item is searchable via the collection. So if I have a resource/item with these parameters:

{ "id": "d6e76f56-b69f-423d-80c1-5ed5395f6602", "userName": "somebody@somewhere.ext", "firstName": "Some", "lastName": "Body", "emailAddress": [ { "email": "somebody@somewhere.ext", "verified": "verified", "source": "IDP" } ], "agencyCode": [ "123" ], "modified": "1477942735", "groups": [ { "agencyCode": "123", "agencyName": "Three Initial Corporation", "groups": [ "Admin", "Power-User" ] } ] }

we should be able to filter based on things like

userName=somebody@somewhere.ext
emailAddress.verified=verified
agencyCode=123

Note that JSON arrays (like the emailAddress) are accessed via arrayName.fieldName.

Note that query parameters are assumed to be case sensitive.

Wildcard Searches

We should also be able to filter with substrings using a wildcard. Currently we use a single * at the end of the string to denote "substring and case insensitive."

queryparam=search*

So if I wanted to find all the people with a first name of something like Joe I could search

/people?firstName=joe*

Which would return records with first names with the case-INsensitive substring "joe"

Joe
Joeline
Bobbyjoe

Numeric operators ($eq | $gt | $lt)

You should be able to filter any numeric field with one of three operators:

$eq: equal to
$gt: greater than
$lt: less than

So, to find records that were modified since Tue, 01 Nov 2016 00:23:12 GMT (or 1477959792), you would search on

/myresource?lastmodified=$gt:1477959792

Null Boolean Test ($exists)

To test for null or non-existent fields use the exists test for false

/myresource?fieldName=$exists:false

To return objects only when a value (any value) exists in the field, test for true:

/myresource?fieldName=$exists:true

Multiselect filter with "$in:"

The API should allow filtering on a list of values, for example, you hav three email addresses and want to return those three items:

/people?emailAddress.email=$in:email@one.com,email@two.com,email@three.com

?size=x

By default the API returns 20 elements. size overrides the default number of elements; so if you want 100 items returned, do size=100 if you only want 1, do size=1

?page=x

Pages start at 0. If a collection returns 100 items with 20 items per page, you would access the last page with page=4.

?sortBy=[fieldname]

Denote which field to sort on, so if you wanted to sort by firstName you would do

/collection?sortBy=firstName

?sortOrder=[asc | desc]

Denotes which way to sort based on the fieldname in the sortBy parameter. So if you wanted Zaphod to come up at the top of the list an Arthur at the bottom you would do

/people?sortBy=firstName&sortOrder=desc

The sort order should default to ascending based on the sortBy if not specified. If no sortBy is specified, no sortOrder is forced and data comes back in native storage results (e.g. however Mogno or SQL Server returns it by default). sortBy must be specified to for sortOrder to make sense.

Sorting on strings should be case insensitive. It makes a lot more sense for a consumer of the API to see:

abracadabra
Kalamazoo
ZAM

Than the alternative:

ZAM
Kalamazoo
abracadabra

Sorting on Multiple Fields

If a consumer of the API wants to sort the response on more than one field, the sortBy and sortOrder need to be passed as comma separated fields. So, if for example, you want to sort people first by agencyCode and then by lastName you would pass

/people?sortBy=agencyCode,lastName&sortOrder=asc,desc

where the result would return groups by agencyCode sorted in ascending order with the people sorted descending by last name. By passing this as a comma separated string we are able to enforce which to sort on first.