RelationshipsBest Practices

Relationship Best Practices


Pair unique: true with preflight when callers need feedback

unique: true silently ignores duplicate edges — no error, no duplicate row. That is correct for idempotent retries but wrong if the API should return ALREADY_FOLLOWING.

Add an explicit preflight reject when duplicate attempts should fail visibly.


Always project relationship events for queries

The relationship store is not exposed to the query service. Subscribe a projection to emit_events types and build a table with upsert / delete mutations.


Use relationships for edges, not cross-entity field updates

You cannot mutate another entity’s balance or counters in core. Use relationship_create for graph semantics; use op: submit in side_effects for cross-stream state changes.


Common mistakes

Expecting unique: true to return an error on duplicates. It does not. Add preflight reject if the caller should know.

Writing cross-stream state mutations in core instead of relationship_create. Use relationships for edges; use submit for other streams.

Not projecting relationship events. Without a projection, you cannot join relationship data in named queries.

Relying on emit_events for custom payload fields. The engine emits relationship metadata. For fields like followed_at, emit explicitly in side_effects instead.


Next steps