Skip to content

Relationships and the graph

Pull related content back with a request using include, expand and depth

Updated View as Markdown

Minima models your content as a knowledge graph: entities connected to other entities by named relationships. A product has a manufacturer, an article mentions a person, a person works at a company.

By default a list or read endpoint gives you records and nothing else. The include parameter tells it to also resolve what those records are connected to, so you can render a page from one request instead of a waterfall of them.

Two projections

There are two ways to get the connected data back, and they are mutually exclusive.

?include=graph

include=graph adds a top-level graph object to the response, keyed by entity ID. Every connected entity appears once, no matter how many records point at it. Look up what you need by ID as you render.

{
  "data": [ ... ],
  "pagination": { ... },
  "graph": {
    "ent_manufacturer1": { "id": "ent_manufacturer1", "name": "Acme", "type": "Company", "..." : "..." },
    "ent_person7": { "id": "ent_person7", "name": "Ada Lovelace", "type": "Person", "..." : "..." }
  }
}
?include=tree

include=tree adds a top-level tree array instead. The same entities are resolved, but nested — each entity carries its related entities inline, and those carry theirs, down to the depth you ask for.

{
  "data": [ ... ],
  "pagination": { ... },
  "tree": [
    {
      "id": "ent_product1",
      "name": "Widget",
      "relationships": {
        "manufacturer": { "id": "ent_manufacturer1", "name": "Acme", "edge": {} }
      }
    }
  ]
}

Reach for graph when you are rendering a list and want to look connections up cheaply. Reach for tree when you are rendering one thing and want its neighbourhood in the shape you will draw it.

Both projections return the same node shape: id, name, type, slug, status, attributes, externalUrl, publishedAt, heroImage, permalink, categories and relationships.

The edge namespace

A relationship can carry its own data — a job title on a works at, a role on a contributed to. That data belongs to the connection, not to either entity, so it lives under a reserved edge key on the related entity:

{
  "id": "ent_person7",
  "name": "Ada Lovelace",
  "edge": { "role": "Lead engineer", "since": "2021" }
}

edge is always present. It is {} when the relationship carries nothing, so you never have to check whether the key exists before reading it.

Depth

?include=tree&depth=2

depth controls how many hops out the tree resolves. The default is 1 — direct relationships only. The maximum is 3, and values above it are clamped rather than rejected.

Depth applies to include=tree only. include=graph is bounded by expand instead.

Expand

?include=graph&expand=manufacturer&expand=manufacturer.country

expand names which relationship branches to follow. Pass it once per path — it is a repeatable parameter, not a comma-separated list and not expand[].

Dots walk the graph. manufacturer pulls in the manufacturer; manufacturer.country pulls in that manufacturer’s country too.

Naming branches matters because a graph has no natural edge. Without expand, a projection either stops at the first hop or drags in everything reachable. expand lets you say exactly which paths your page actually renders.

Articles are a special case

An article does not name its related entities through a relationship. It mentions them — you link an entity from the article body, and Minima records the mention.

That means you never write expand=mentions. Mentioned entities are collected for you whenever you ask for a projection. What expand names on an article request is a relationship on the mentioned entities, one level further out.

Take an article about a record that mentions an album, where the album has a byArtist relationship. include=tree resolves one hop by default, so the mentioned album arrives with its artist already attached:

curl -G "https://api.minima.ltd/api/v1/public/sites/site_abc123/articles/slug/mentioned-music" \
  --data-urlencode "include=tree" \
  -H "x-api-key: pub_your_key_here"
{
  "id": "art_abc123",
  "headline": "Mentioned music",
  "tree": [
    {
      "id": "ent_album1",
      "name": "Mentioned Album",
      "type": "MusicAlbum",
      "relationships": {
        "byArtist": { "id": "ent_artist1", "name": "Mentioned Artist", "edge": {} }
      }
    }
  ]
}

For the flat projection, name the branch you want from the mentioned entity:

curl -G "https://api.minima.ltd/api/v1/public/sites/site_abc123/articles/slug/mentioned-music" \
  --data-urlencode "include=graph" \
  --data-urlencode "expand=byArtist" \
  -H "x-api-key: pub_your_key_here"

One request, one round trip, and every entity you need to render the page is in graph under its ID.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close