reym
Projections/Schema/Object

@upsertOn

A projection definition requires one or multiple @upsertOn type directives.

Example

In the following case the createUser event will upsert data to the dataset identified by the value of its id payload field. The updateUser event will upsert data to the dataset identified by its userId payload field.

user.graphql
type User
    @upsertOn(
        on: {
            topic: "userManagement"
            eventTypes: ["createUser"]
        }
        identifyBy: { payload: ["id"] }
    )
    @upsertOn(
        on: {
            topic: "userManagement"
            eventTypes: ["updateUser"]
        }
        identifyBy: { payload: ["userId"] }
    ) {
    // ...
}

Arguments

You can use the following arguments on the @upsertOn directive directly:

ArgumentDescription
onrestrict updates of the projection
identifyByspecify how the identifier of the data is generated
filterByupsert entries in the projection by a filter

Argument on

If eventTypes and topic are both specified for the on argument, an event has to match both to be considered for the projection.

ArgumentDescription
eventTypesrestrict updates to the projection to a list of event types
topicrestrict updates to the projection to a topic string

Argument identifyBy

Specify how the identifier of the data is generated. The generated identifier separates all parts by a - character.

ArgumentDescription
attributesspecify a list of attributes that should be part of the identifier
payloadspecify a list of event payload fields that should be part of the identifier

Applying this to an example, the @upsertOn directive will generate the id streamName-uuid for an event of the stream called streamName and with a payload {"id": "uuid"}:

@upsertOn(
    on: { 
        topic: "userManagement"
        eventTypes: ["createUser"]
    }
    identifyBy: { attributes: ["stream"], payload: ["id"] }
)

Available Event Attributes

The events to trigger an upsert operation can be filtered using the following attributes:

AttributeDescription
idthe identifier of the event
tenantIdthe identifier of the tenant
topicthe topic to which the event was published to
typename of the event type
streamname of the used stream
correlationIdcorrelation identifier
causationIdcausation identifier
reasonthe reason why the event was published

Argument filterBy

Alternative to the identifyBy argument, you can use the filterBy argument to specify a filter that determines which data should be upserted in the projection.

user.graphql
type User
    @upsertOn(
        on: {
            topic: "userManagement"
            eventTypes: ["createUser"]
        }
        filterBy: { fields: [{
            projectionField: "name"
            operation: "equals"
            type: "String"
            eventField: "userName"
        }] }
    ){
    // ...
}

This example shows how to use the filterBy argument to upsert data in the projection based on a filter. In this case, the createUser event will upsert data in the projection if the name field of the projection matches the userName field of the event.

Types and operations

TypeAllowed operations
IDequals, notEquals, in, notIn
[ID]inArray, notInArray, lengthEq, lengthNotEq, lengthGt, lengthGtOrEq, lengthLt, lengthLtOrEq, empty, notEmpty
Stringequals, notEquals, equalsCaseInsensitive, notEqualsCaseInsensitive, in, notIn, contains, notContains, containsCaseInsensitive, notContainsCaseInsensitive
[String]inArray, notInArray, lengthEq, lengthNotEq, lengthGt, lengthGtOrEq, lengthLt, lengthLtOrEq, empty, notEmpty
Fileequals, notEquals, in, notIn
DateTimeequals, notEquals, in, notIn, before,beforeOrAt,after,atOrAfter
[DateTime]inArray, notInArray, lengthEq, lengthNotEq, lengthGt, lengthGtOrEq, lengthLt, lengthLtOrEq, empty, notEmpty
Intequals, notEquals, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual
[Int]inArray, notInArray, lengthEq, lengthNotEq, lengthGt, lengthGtOrEq, lengthLt, lengthLtOrEq, empty, notEmpty
Floatequals, notEquals, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual
[Float]inArray, notInArray, lengthEq, lengthNotEq, lengthGt, lengthGtOrEq, lengthLt, lengthLtOrEq, empty, notEmpty
Booleanequals, notEquals

The in and notIn filters require an array as value. The inArray and notInArray filters allow arrays or single values.