Filters
Filters allow you to permit and route events conditionally based on the contents of their Headers
, Body
, Query
, or Path
.
The two most common uses of filters are:
- Allowing only events with useful information to pass through to a destination.
- Routing events to different destinations based on their contents, as in a fan out approach.
Filters utilize JSON, and support matching on any value (string, number, boolean, null
), on nested objects, and on arrays. There is also support for special operators. For a full rundown of supported schema, see filter syntax.
Filter limitations
Filters were designed for JSON payloads. To filter XML payloads, please first transform the payload to JSON.
Basic, non-structured filters, such as partial or exact matches on strings, will function with XML payloads.
Filters syntax
Filters utilize JSON, and support matching on any value (string, number, boolean, null
), on nested objects, and on arrays.
The following events would be permitted through the filter, based on their request bodies and respective filters.
Simple matches
Single value match
// Event request body
false
// Filter
false
Simple primitive match
// Event request body
{
"type": "order/created",
"order": {
"id": 123
}
}
// Filter
{
"type": "order/created"
}
Nested object match
// Event request body
{
"product": {
"title": "A product",
"inventory": 0
}
}
// Filter
{
"product": {
"inventory": 0
}
}
Also valid:
// Event request body
{
"order": {
"id": 123,
"items": [
{
"id": 456,
"title": "My product"
}
]
}
}
// Filter
{
"order": {
"items": {
"id": 456
}
}
}
Array contains match
// Event request body
{
"product": {
"title": "Gift Card",
"tags": ["gift", "something"]
}
}
// Filter
{
"product": {
"tags": "gift"
}
}
Array contains (multiple) match
Array must contain all the specified values.
// Event request body
{
"product": {
"title": "Gift Card",
"tags": ["gift", "something", "another"]
}
}
// Filter
{
"product": {
"tags": ["gift", "something"]
}
}
Non-object match
To match on a string that is not part of an object structure (for example, to set a filter on a path), simply consider the string to be at the root of your filter:
// Path
"/path/test"
// Filter
{
"$in": "/path"
}
Complex matches using operators
Operators allow for more complex matching strategies, beyond simple equivalency tests.
Operator | Supported Type | Description |
---|---|---|
$gte | number , string | Greater than or equal to |
$gt | number , string | Greater than |
$lt | number , string | Less than |
$lte | number , string | Less than or equal to |
$eq | array , number , object , string | Equal (or deep equal) |
$neq | array , number , object , string | Not Equal (or deep not equal) |
$in | array , string | Contains |
$nin | array , string | Does not contain |
$startsWith | string | Starts with text |
$endsWith | string | Ends with text |
$or | array | Array of conditions to match |
$and | array | Array of conditions to match |
$ref | <field> | Reference a field |
$exist | boolean | Undefined or not undefined |
$not | Valid syntax | Negation |
Value comparison operators
The following demonstrates a matching filter using the $lte
(less than or equal to) operator.
// Event request body
{
"product": {
"title": "A product",
"inventory": 5
}
}
// Filter
{
"product": {
"inventory": {
"$lte": 10
}
}
}
$or and $and operators
$or
and $and
evaluate matches across an array of values. The array of conditions can contain any other valid schema.
The following demonstrates a matching filter using the $or
operator.
// Event request body
{
"product": {
"title": "A product",
"inventory": 5
}
}
// Filter
{
"product": {
"inventory": {
"$or": [1, 5]
}
}
}
The following demonstrates a non-matching filter using the $or
operator.
// Event request body
{
"hello": "world"
}
// Non-matching filter
{
"$or": [
{ "hello": "johny"},
{ "hello": "mark"}
]
}
Reference operator
$ref
references other values in your JSON input when evaluating a match. The reference input must be a string representing the value path.
// Event request body
{
"type": "example",
"nested_object": {
"hello": "world",
"array": [1, 2, 3]
}
}
// Example reference values
"$ref" : "type" // evaluates to "example"
"$ref" : "nested_object.hello" // evaluates to "world"
"$ref" : "nested_object.array[1]" // evaluates to 1
"$ref" : "nested_object.array[$index]" // evaluates to 1, 2, or 3 (depending on the current index)
The following demonstrates a matching filter using the $ref
operator.
// Event request body
{
"updated_at": "2020-04-20",
"created_at": "2020-04-20"
}
// Filter
{
"updated_at": {
"$ref": "created_at"
}
}
You may also reference the current array index, instead of a specific index, using $index
. Multiple indexes can be referenced when dealing with nested arrays.
// Event request body
{
"variants": [
{
"updated_at": "2020-05-20",
"created_at": "2020-04-20"
},
{
"updated_at": "2020-04-20",
"created_at": "2020-04-20"
}
]
}
// Filter: Test if any of the elements in the array has the same value for `updated_at` and `created_at`.
// This will match because the 2nd element has the same date for both `updated_at` and `created_at`.
{
"variants": {
"updated_at": {
"$eq": {
"$ref": "variants[$index].created_at"
}
}
}
}
$ref
may also be used in conjunction with other operators.
// Event request body
{
"inventory": 0,
"old_inventory": 10
}
// Filter
{
"inventory": {
"$lte": { "$ref": "old_inventory" }
}
}
$exist operator
$exist
requires a field to be undefined when false and array, number, object, string, boolean or null when true.
// Event request body
{
"inventory": 0,
}
// Filter
{
"old_inventory": {
"$exist": false
}
}
Negation operator
$not
negation of the schema.
// Event request body
{
"inventory": 0,
}
// Filter
{
"$not": {
"inventory": 1,
}
}
Examples using operators
Example 1 - Filter if property = value (nested)
Condition Don't allow "subtype" = "message_changed" OR "subtype" = "message_deleted"
// Event request body
{
"event": {
"type": "message",
"subtype": "message_changed"
}
}
// Filter
{
"$not": {
"event": {
"subtype": {
"$or": [
"message_changed",
"message_deleted"
]
}
}
}
}
Example 2 - Two properties meet criteria with 'or' condition
Condition Only allow "subtype" = "message_changed" OR "subtype" = "message_deleted" AND "type"="message"
// Event request body
{
"event": {
"type": "message",
"subtype": "message_changed"
}
}
// Filter
{
"event": {
"subtype": {
"$or": [
"message_changed",
"message_deleted"
]
},
"type": "message"
}
}
Example 3 - using $not and $or operators
Condition
- Allow "event" = "message"
- AND don't allow "team_id" = "team1" OR "team_id" = "team2"
- AND if "subtype" exists, don't allow "subtype" = "message_changed" OR "subtype" = "message_deleted"
// Event request body
{
"team_id": "team",
"event": {
"type": "message",
"subtype": "message_changed"
}
}
// Filter
{
"event": {
"type": "message"
},
"$not": {
"$or": [
{
"event": {
"subtype": {
"$or": [
"message_changed",
"message_deleted"
]
}
}
},
{
"team_id": {
"$or": [
"team1",
"team2"
]
}
}
]
}
}
Example 4 - using $not and $endsWith
Condition Don't allow where "subtype" ends with "message_changed"
// Event request body
{
"event":{
"type":"message",
"subtype":"some_message_changed"
}
}
// Filter
{
"event":{
"$not":{
"subtype":{
"$endsWith": "message_changed"
}
}
}
}
Create a filter
Filters are applied to a connection, just like any other rule.
To version control your filters, consider creating or updating your connection using the API.
Open the connection rules configuration.
Click
to add a filter rule.Click Editor to configure the filter.
- To add a filter for the
Body
,Headers
,Query
, orPath
, select the appropriate tab above the editor. - In the right pane, enter the desired schema using proper filter syntax.
- The left pane shows the most recent payload for reference and testing purposes. This reference text is editable.
- To add a filter for the
Once written, test your filter against the event in the left pane by clicking
. A check mark next to eachBody
,Headers
,Query
, orPath
section indicates the event would be allowed through to its destination based on the contents of that section.Once satisfied, click
.Make sure to click
again on the connection form to apply your changes.
From this point on, any events not matching the filter are disregarded by Hookdeck, and will not appear in your list of events.
Edit a filter
Editing a filter changes the schema that determines a event's delivery eligibility.
Open the connection rules configuration.
Next to the filter rule, click Editor.
- To edit a filter for the
Body
,Headers
,Query
, orPath
, select the appropriate tab above the editor. - In the right pane, update the desired schema using proper filter syntax.
- In the left pane appears the most recent payload for reference and testing purposes. This reference text is editable.
- To edit a filter for the
Once written, test your updated filter against the event in the left pane by clicking
. A check mark next to eachBody
,Headers
,Query
, orPath
section indicates the event would be allowed through to its destination based on the contents of that section.Once satisfied, click
.Make sure to click
again on the connection form to apply your changes.
Filters are updated immediately, and any events received going forward are tested against the new filter contents.
Delete a filter
Deleting a filter allows all events, regardless of content, to pass through a connection unimpeded.
To delete a filter, follow the instructions for configuring connection rules and click the trash icon to remove the filter from the connection rules.