Skip to content

Relations

Alejandro Lugo edited this page Jun 7, 2026 · 2 revisions

Relations

yrest supports simple one-to-many relations declared in the _rel block of your YAML file. Relations power ?_expand, ?_embed and nested routes.


Declaring relations

Add a _rel block at the top level of your YAML file:

_rel:
  posts:           # child collection
    userId: users  # foreign key field: parent collection

Format:

_rel:
  <child_collection>:
    <foreign_key_field>: <parent_collection>

A child collection can have multiple foreign keys:

_rel:
  comments:
    userId: users
    postId: posts

Full example

_rel:
  posts:
    userId: users
  comments:
    userId: users
    postId: posts

users:
  - id: 1
    name: Alice
  - id: 2
    name: Bob

posts:
  - id: 1
    title: Hello world
    userId: 1
  - id: 2
    title: Second post
    userId: 1

comments:
  - id: 1
    body: Great post!
    userId: 2
    postId: 1

?_expand — embed parent into child

When querying a child collection, use ?_expand to embed the parent object inline.

GET /posts/1?_expand=user
{
  "id": 1,
  "title": "Hello world",
  "userId": 1,
  "user": {
    "id": 1,
    "name": "Alice"
  }
}

yrest resolves the expand key by stripping the Id suffix from the foreign key (userIduser) and matching against the parent collection name.

Multiple parents:

GET /comments/1?_expand=user,post

?_embed — embed children into parent

When querying a parent collection, use ?_embed to embed its child items inline.

GET /users/1?_embed=posts
{
  "id": 1,
  "name": "Alice",
  "posts": [
    { "id": 1, "title": "Hello world", "userId": 1 },
    { "id": 2, "title": "Second post", "userId": 1 }
  ]
}

Parents with no matching children receive an empty array.

Works on collections too:

GET /users?_embed=posts

Nested routes

For each declared relation, yrest automatically registers nested routes:

GET /users/1/posts          → all posts where userId === 1
GET /users/1/posts/2        → post 2 only if userId === 1

Both routes return 404 if the parent does not exist. The item route also returns 404 if the child does not belong to that parent.


?_expand vs ?_embed at a glance

Direction Queried from Result
?_expand child → parent child collection parent object embedded in child
?_embed parent → children parent collection array of children embedded in parent

Both use the same _rel declaration — the direction depends on which side you query from.


Combining expand and embed

You can use both in the same request if the resource is both a child and a parent:

# posts are children of users, and parents of comments
GET /posts/1?_expand=user&_embed=comments
{
  "id": 1,
  "title": "Hello world",
  "userId": 1,
  "user": { "id": 1, "name": "Alice" },
  "comments": [
    { "id": 1, "body": "Great post!", "userId": 2, "postId": 1 }
  ]
}

Clone this wiki locally