JsonPath Functions

This page describes how to use the built-in JsonPath support to process event data into projections.

To create useful projections we need to merge the event data with the projection data in different ways. We provide templating support built on JsonPath to support this out-of-the-box.

If the templating support we provide is too restricted for your use-case we encourage you to write your own projector, deployed either as an external function (hosted on eg. AWS) or external service using the Feed API and a storage of your choice. Read more about customized projectors in the next chapter.

The structure of a handler using the provided JsonPath templating looks like this:

{
"eventType": "<YOUR_EVENT_TYPE>",
"functions": [
{
"function": "merge",
"targetSelector": "$.projection",
"eventSelector": "$.event"
}]
}

This example will merge the content of the incoming event by using the JsonPath selector $.event with the current state of the projection by targeting the full projection state using the JsonPath selector $.projection.

In a handler function you always have access to $.event (the current event being handled) and $.projection (the current projection state).

The above example can also be simplified to:

{ "function": "merge" }

since the default values for targetSelector and eventSelector are $.event and $.projection, respectively.

Providing raw data

If you have a static value that you want to use as the data for the projection instead of some value that is provided in the event, you can use the rawData argument instead of the eventSelector. You can then provide any JSON value which will be used as-is.

rawData and eventSelector are always mutual exclusive, so make sure you only provide one of them in your function configuration.

Basic object modification

merge

Merges event data with existing projected data.

Argument

Evaluated Type

Required

targetSelector

Object

Yes

eventSelector

Object

No

targetFilter

Not used

No

eventFilter

Not used

No

rawData

Object

No

{
"eventType": "OrderStatusChangedEvent",
"functions": [
{
"function": "merge"
}
]
}

set

Replaces the value of an existing key.

Argument

Evaluated Type

Required

targetSelector

Any

Yes

eventSelector

Any

No

targetFilter

Filter expression

No

eventFilter

Filter expression

No

rawData

Any

No

{
"eventType": "EmailUpdatedEvent",
"functions": [
{
"function": "set",
"targetSelector": "$.projection.user.email",
"eventSelector": "$.event.newEmail"
}
]
}

clear

Clear an entire projection's data.

Argument

Evaluated Type

Required

targetSelector

Not used

No

eventSelector

Not used

No

targetFilter

Filter expression

No

eventFilter

Filter expression

No

rawData

Not used

No

{
"eventType": "UserDeletedEvent",
"functions": [
{
"function": "clear"
}
]
}

delete

Delete a projection instance

Argument

Evaluated Type

Required

targetSelector

Not used

No

eventSelector

Not used

No

targetFilter

Filter expression

No

eventFilter

Filter expression

No

rawData

Not used

No

{
"eventType": "UserDeletedEvent",
"functions": [
{
"function": "delete"
}
]
}

Working with arrays/lists

push

Adds anything to the end of an array.

Argument

Evaluated Type

Required

targetSelector

Array

Yes

eventSelector

Any

No

targetFilter

Filter expression

No

eventFilter

Filter expression

No

rawData

Any

No

{
"eventType": "RunnerFinishedRaceEvent",
"functions": [
{
"function": "push",
"targetSelector": "$.projection.finishers",
"eventSelector": "$.event['runnerName','finishTime']"
}
]
}

prepend

Adds anything to the beginning of an array.

Argument

Evaluated Type

Required

targetSelector

Array

Yes

eventSelector

Any

No

targetFilter

Filter expression

No

eventFilter

Filter expression

No

rawData

Any

No

{
"eventType": "TodoAddedEvent",
"functions": [
{
"function": "prepend",
"targetSelector": "$.projection.todos",
"eventSelector": "$.event['todoId','todoText']"
}
]
}

remove

Removes an existing key or an array element matching filter expression.

Argument

Evaluated Type

Required

targetSelector

Any

Yes

eventSelector

Not used

No

eventFilter

Not used

No

targetFilter

Filter expression

Yes

rawData

Not used

No

{
"eventType": "TodoRemovedEvent",
"functions": [
{
"function": "remove",
"targetSelector": "$.projection.todos[?]",
"targetFilter": "[?(@.todoId == $.event.todoId)]"
}
]
}

Performing arithmetic

add

Sums two numbers together.

Argument

Evaluated Type

Required

targetSelector

Number

Yes

eventSelector

Number

No

eventFilter

Not used

No

targetFilter

Not used

No

rawData

Number

No

{
"eventType": "OrderPlacedEvent",
"functions": [
{
"function": "add",
"targetSelector": "$.projection.totalAmount",
"eventSelector": "$.event['orderAmount']"
}
]
}

subtract

Subtracts two numbers.

Argument

Evaluated Type

Required

targetSelector

Number

Yes

eventSelector

Number

No

eventFilter

Not used

No

targetFilter

Not used

No

rawData

Number

No

{
"eventType": "OrderRefundedEvent",
"functions": [
{
"function": "subtract",
"targetSelector": "$.projection.totalAmount",
"eventSelector": "$.event['orderAmount']"
}
]
}

inc

Increases a number by one.

Argument

Evaluated Type

Required

targetSelector

Number

Yes

eventSelector

Not used

No

targetFilter

Filter expression

No

targetFilter

Not used

No

rawData

Not used

No

{
"eventType": "TicketReservedEvent",
"functions": [
{
"function": "inc",
"targetSelector": "$.projection.ticketCount"
}
]
}

dec

Decreases a number by one.

Argument

Evaluated Type

Required

targetSelector

Number

Yes

eventSelector

Not used

No

targetFilter

Filter expression

No

targetFilter

Not used

No

rawData

Not used

No

{
"eventType": "TicketReleasedEvent",
"functions": [
{
"function": "dec",
"targetSelector": "$.projection.ticketCount"
}
]
}

Adding lookup via references

You can make your projections

setRef

Marks a projection field as a reference which makes it searchable in the API.

Argument

Evaluated Type

Required

targetSelector

String/Number/Date

Yes

eventSelector

Not used

No

targetFilter

Not used

No

targetFilter

Not used

No

rawData

Not used

No

{
"eventType": "TicketReleasedEvent",
"functions": [
{
"function": "setRef",
"targetSelector": "$.projection.releaseDate"
}
]
}

clearRef

Clears the reference for the projection, removing it from the searchable index.

Argument

Evaluated Type

Required

targetSelector

Not used

No

eventSelector

Not used

No

targetFilter

Not used

No

targetFilter

Not used

No

rawData

Not used

No

{
"eventType": "TicketReleasedEvent",
"functions": [
{
"function": "clearRef"
}
]
}

Filters

Functions can also provide two filters: targetFilter and eventFilter.

To add a filter to a selector you provide a [?] in the selector text, as described in the JsonPath documentation. The filter for the selector is then applied for the given function. This is useful for matching on ids in nested lists or to apply conditional logic for when/how to process events.

All Filter Operators that are described here are supported.