Skip to content

Relations (Eager Loading) ​

Load related entities alongside the main resource using the with query parameter.

Syntax ​

?with=relation1,relation2

Nested Relations ​

Use dot notation to load nested relations:

?with=categories.translations
?with=categories.articles.translations

Self-Relations (Recursive) ​

For tree structures (e.g., categories with children), use the * wildcard to load all levels:

?with=children*                    # Load all descendant levels
?with=children*.translations       # Load all levels with their translations

Multiple Relations ​

Combine relations with commas:

?with=translations,categories.translations,vendor,images

Available Relations ​

Each endpoint's tag description lists its supported relations. Requesting an unsupported relation is silently ignored.

Scope-Based Filtering ​

Scope-based relation filtering is opt-in per controller — it only applies where rest_policies.php declares a relations allow-list for that controller. Today that's Customer and Line only. For every other endpoint, no allow-list is defined, so RelationFilterMiddleware does not filter at all: any relation the endpoint supports (per its tag description / x-relations) is available regardless of scope.

Where a controller does declare an allow-list, the available set depends on your authentication scope:

ScopeBehavior
PublicOnly public-safe relations are available
CustomerPublic relations + customer-specific relations
BackendAll relations available

If you request a relation that isn't allowed for your scope, it is silently stripped from the response (no error returned). See the REST Middleware & RBAC guide for the full mechanism and the current allow-lists.

This enforcement is per endpoint, not per entity. Relation loading recurses across entity boundaries, so denying a relation on one controller does not deny that data platform-wide. If the related entity is itself exposed by another guest-readable endpoint — or reachable through a relation declared on one — and that other endpoint has no relations allow-list of its own, the denied data is still reachable by nesting through it.

Constrain Parameter ​

By default, relations inherit the parent query's filters where applicable. To disable this:

?with=categories&constrain=false

Discovering Relations from the OpenAPI Spec ​

Each resource's OpenAPI tag includes a vendor extension x-relations that lists all available relations with their cardinality type:

CardinalityMeaning
belongs_toThe entity holds a foreign key to the related entity (e.g., product belongs to vendor)
one_to_manyThe related entity holds a foreign key back to this entity (e.g., product has many images)
many_to_manyA pivot table connects the two entities (e.g., product has many categories)

Example x-relations excerpt from a tag definition:

yaml
x-relations:
  translations:
    type: one_to_many
  categories:
    type: many_to_many
  vendor:
    type: belongs_to
  images:
    type: one_to_many

Use these vendor extensions to programmatically discover which relations are available for each resource and understand their cardinality without trial and error.