📨 Typescript DSL for expressive AWS SNS filter policies as type-safe code.
- 📦 Type-Safe DSL: Define AWS SNS filter policies using a type-safe TypeScript DSL.
- 🧩 Composable: Build complex filter policies using logical operators and nested conditions in TypeScript.
- 🛠️ Use it Anywhere: Usable with the JavaScript AWS SDK and the AWS CDK.
- 📚 Versioned Types: Allows you to define and version your types transiting through AWS SNS.
sns-filter is a Typescript Domain-Specific Language (DSL) making it easy to write AWS SNS filter policies in a type-safe way, whether you're creating policies using the AWS SDK or the AWS Cloud Development Kit (CDK).
ℹ️ Filter policies adhere to the Filter Policy Language and make it possible in AWS SNS to filter events based on message attributes or message payloads transiting through an AWS SNS topic, allowing users to control how events flow through the fan-out process.
Creating a conditional statement as a filter is simple and expressive using the when primitive. Here we are using the equals operator to check if the data.value attribute is equal to the string foo.
equals accepts both string and number values.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The equalsIgnoreCase operator checks if a specific string attribute matches a given value, ignoring case sensitivity.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The exists operator checks if a specific attribute, whatever its type, exists in the message. This is useful for filtering messages based on the presence of certain attributes.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The startsWith operator checks if a string attribute starts with a given string value. This is useful for filtering messages based on prefixes.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The endsWith operator checks if a string attribute ends with a given value. This is useful for filtering messages based on suffixes.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The lt, lte, gt, and gte operators are used to compare numeric attributes. They respectively check whether a numeric attribute is less than, less than or equal to, greater than, or greater than or equal to a specified value.
In AWS SNS, numeric attributes can refer to both integers and floating-point numbers with at most 5 digits of precision.
Below is the resulting filter policy in JSON format using the lt operator, which is generated by the value() method.
The between operator checks if a numeric attribute falls within a given range (inclusive). This is useful for filtering messages based on numeric ranges.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The includes operator checks if an attribute—string or numeric—contains a given value. This allows to define simple OR conditions based on the value attribute of a single attribute.
Note that mixing strings and numbers is not supported in the same includes condition.
See the resultBelow is the resulting filter policy in JSON format using the includes operator with strings, which is generated by the value() method.
Below is the resulting filter policy in JSON format using the includes operator with numbers, which is generated by the value() method.
The matches operator checks if a string attribute matches a given pattern. Today, it only supports matching a string attribute against an IPv4 CIDR value.
If the passed value is not a valid IPv4 CIDR, an exception will be raised at runtime.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The power of this DSL lies in fluently composing multiple conditions using logical operators such as and, or, and not. This allows you to create complex filter policies that can handle more complex scenarios.
The not operator simply negates a condition, allowing to filter messages that do not match a specific attribute or value. It can be used with the above operators to create more complex filter policies.
Note that AWS SNS does not support negation on all conditional operators, please refer to the AWS SNS documentation for more details. If you attempt to use not with an unsupported operator, an exception will be raised at runtime.
Below is the resulting filter policy in JSON format using the equals operator.
Below is the resulting filter policy in JSON format using the exists operator.
Below is the resulting filter policy in JSON format using the startsWith operator.
The and operator allows you to combine multiple conditions, ensuring that all specified conditions must be true for the filter to match. This is useful for creating filters that require multiple attributes or values to match a certain criteria.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
You can chain multiple and conditions together to add more conditions to the filter.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
In AWS SNS, the and operator cannot be used on the same attribute multiple times. For example, you cannot have a conditional that checks if data.value is equal to foo and another conditional that checks whether data.value is greater than 10 in the same filter policy.
⚠️ The below example will raise an exception at runtime.
The or operator allows you to define a filter policy to express an OR relationship between multiple attributes in the policy.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
You can chain multiple or conditions together to create more complex filters. Note that will create a multi-operand OR condition, meaning that any of the conditions can match for the filter to be considered valid.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
The order and hierarchy in which you are using the or operator does matter and impacts the precedence of conditional statements. For example, the following filter will be evaluated as (data.type == 'foo') OR ((data.type != 'bar') OR (data.status == 'active')).
Below is the resulting filter policy in JSON format, which is generated by the value() method.
You can combine and and or operators to create even more complex filter policies.
Below is the resulting filter policy in JSON format, which is generated by the value() method.
While the when primitive allows for some type-safety, ensuring you are defining the correct types for your operands, it does not check whether the rule you are defining is valid for the type of the data you are using.
This where the TypedCondition primitive comes in which takes in the concrete type of the event you are creating a filter for.
The difference is that the TypedCondition primitive will ensure that the path you are using to define your filter is valid for the, and that the operands you are using actually match the type of the event you are filtering.
For example, if you pass in a path that does not exist in the type, a compile-time error will be raised.
This also allows the typed interface to provide you with a nice auto-completion experience in your IDE, making it easier to define your filter policies.
The TypedCondition primitive also ensures that the operands you are using match the type of the event you are filtering. For example, if you try to use a numeric operand such as lt on a string attribute, a compile-time error will be raised.
Often the events sent over an AWS SNS topic can be of different types, and you may want to filter based on the possible types of events. You can use union types with the TypedCondition primitive to define a filter that can handle multiple event types.
.png)


