Relations
Relations define how resources reference each other. A relation field creates a foreign key link from one resource to another, enabling you to model associations like "a post belongs to a user" or "a student enrolls in many courses."
Defining a Relation
Add a field with type: "relation" and include a relations object specifying
the target resource, the target field, and the relation type:
{
"name": "author_id",
"type": "relation",
"relations": {
"resource": "users",
"field": "id",
"type": "many-to-one"
}
}
Relations Object
| Property | Type | Description |
|---|---|---|
resource |
string | Name of the related resource (required) |
field |
string | Field on the related resource to join on |
type |
string | One of the four relation types listed below |
Relation Types
One-to-One
Each record in the source resource maps to exactly one record in the target resource, and vice versa.
{
"name": "profile_id",
"type": "relation",
"relations": { "resource": "profiles", "field": "id", "type": "one-to-one" }
}
Use case: a users resource has one profiles record.
One-to-Many
A single record in the source resource can be referenced by many records in the target resource. This is defined on the "one" side.
{
"name": "category_id",
"type": "relation",
"relations": {
"resource": "categories",
"field": "id",
"type": "one-to-many"
}
}
Use case: a categories resource has many products.
Many-to-One
Many records in the source resource point to a single record in the target resource. This is the inverse of one-to-many and is the most common relation type.
{
"name": "author_id",
"type": "relation",
"relations": { "resource": "users", "field": "id", "type": "many-to-one" }
}
Use case: many posts belong to one users record.
Many-to-Many
Records on both sides can reference multiple records on the other side. Snaapi manages the join internally.
{
"name": "tag_ids",
"type": "relation",
"relations": { "resource": "tags", "field": "id", "type": "many-to-many" }
}
Use case: posts can have many tags, and each tags record can appear on
many posts.
Query Behavior
When you read a resource that contains relation fields, Snaapi resolves the relations automatically. The query response includes the related data based on the relation type and the permissions of the requesting role.
- Filtering — You can filter by relation fields using the standard filter
operators (e.g.,
author_id eq <uuid>). - Sorting — If the relation field is marked
sortable, results can be ordered by the foreign key value. - Permissions — Relation fields are subject to the same field-level permission rules as any other field. A role must have access to the relation field to see or filter by it.
- Existence checks — Use the
exists/not_existsfilter operators to query based on whether a related record is present.