API Series: Expands and Filters

Any API is really all about one thing: data. An API needs to accept data, do something with it, then give data back. For the consumer of an API, what happens in that middle part doesn’t matter. All they care about is that they sent the API some data to work with and the API returned data to them in a format they expect. And a big part of data for an API is being able to support rich querying capabilities so that the client gets back exactly what they need. For the Znode API, this is handled by expands and filters.


The concept of expands is nothing new in API design, as many APIs support them, and even our own implementation is loosely based on the OData specification for expands. In short, expands is a way of asking for related data during the same request. For example, when retrieving a product, you might also want to get its customer reviews and any categories it belongs to. Without expands, you might have to do this in three separate calls, perhaps something like this:

GET /products/123 GET /products/123/reviews GET /products/123/categories

But with expands, you can consolidate those three calls into one, like so:

GET /products/123?expand=reviews,categories

You can chain as many expands together as you need, simply use a comma to separate them (a configurable option we’ll cover in a later post). And that’s the big benefit of expands – to eliminate extraneous API calls that you can otherwise handle with one call.


Similar to expands, filters were also roughly based on their OData specification. Using filters allow you to retrieve only the data that satisfies an expression; think of filters as the WHERE clause in a SQL statement. For example, you might want to retrieve a list of products that have a retail price greater than $5.00. With filters, the URL request would look like this:

GET /products?filter=retailprice~gt~5.00

Also like expands, you can chain filters together. For example, you want to retrieve a list of products that have a retail price greater than $5.00, but only for products whose name starts with the letter A. The request for that would look like this:

GET /products?filter=retailprice~gt~5.00,name~sw~A

Filter expressions are basically tuples that consist of the following format:


The tilde character (~) is used as the default separator between key/operator/value, while the comma is used to separate multiple filter expressions (both of which are configurable). Below is the list of currently supported filter operators:

Operator Description Example
eq Equal to GET /products?filter=name~eq~apple
ne Not equal to GET /products?filter=name~ne~apple
cn Contains GET /products?filter=name~cn~pea
gt Greater than GET /products?filter=retailprice~gt~4.99
ge Greater than or equal to GET /products?filter=retailprice~ge~5.00
lt Less than GET /products?filter=retailprice~lt~5.00
le Less than or equal to GET /products?filter=retailprice~le~4.99
sw Starts with GET /products?filter=name~sw~app
ew Ends with GET /products?filter=name~ew~pple

Filters in the Znode API can also be used to query for nullable items by using a “null” value for the eq (equal to) and ne (not equal to) operators, as such:

GET /products?filter=externalid~eq~null GET /products?filter=externalid~ne~null

Powerful and Flexible

When it comes to querying data from an API, expands and filters are important because it gives clients great power and flexibility for how they want to retrieve data, and the Znode API has very robust expand and filter capabilities.