Relationship Examples
From the Concert App tutorial.
Artist followers and show going
# relationships/follow.relationships.causet
relationships:
artist_followers:
from: user
to: artist
cardinality: many_to_many
unique: true
emit_events:
created: ARTIST_FOLLOWED
removed: ARTIST_UNFOLLOWED
show_going:
from: user
to: show
cardinality: many_to_many
unique: true
emit_events:
created: USER_MARKED_GOINGunique: true makes duplicate follow or going attempts idempotent at the engine level.
Creating an edge from an intent
actions:
FOLLOW_ARTIST:
state: user
entity_id_expr: intent.user_id
input:
user_id: { type: string, required: true }
artist_id: { type: string, required: true }
preflight:
rules:
- name: not_already_following
when: { expr: "LOOKUP_IS_FOLLOWING == true" }
then:
- op: reject
code: ALREADY_FOLLOWING
core:
rules:
- name: create_follow
when: {}
then:
- op: relationship_create
relationship: artist_followers
from_id: intent.user_id
to_id: intent.artist_idProjecting edges for queries
projections:
user_following:
source_events: [ARTIST_FOLLOWED, ARTIST_UNFOLLOWED]
target:
table: user_following
primary_key: [user_id, artist_id]
fields:
user_id: TEXT
artist_id: TEXT
followed_at: BIGINT
derive:
user_id: event.user_id
artist_id: event.artist_id
followed_at: event.ts
mutations:
ARTIST_FOLLOWED: { op: upsert }
ARTIST_UNFOLLOWED: { op: delete }Then join in a query — see Query Examples.
More examples
| Example | Relationships demonstrated |
|---|---|
| Concert App | Full relationship + action wiring |
| Projection Examples | user_following materialization |
| Intent Examples | FOLLOW_ARTIST with preflight |
Next steps
- Defining Relationships — schema reference
- Listeners — sync follower count without a projection lag