---
title: "Academy Article"
canonical_url: "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers"
locale: en
meta:
  "og:title": "Academy Article"
---

[Go to home](https://academy.laioutr.com/en)

- [For developers](https://academy.laioutr.com/en/bereiche/for-developers)

- [Developer start](https://academy.laioutr.com/en/leitfaeden/developer-start)

- [Orchestr: entities, queries, actions and resolvers](https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers)

# Orchestr: entities, queries, actions and resolvers

Orchestr is Laioutr's data layer and runs server-side in the Nuxt server. Queries return entity IDs, component resolvers load the data for them, actions perform changes, and tokens form the contract between frontend, Orchestr and apps.

## Before you start

<dl>

<dt>Duration</dt>
<dd>8 min</dd></dl>

Last reviewed on October 15, 2026

Orchestr organises data as **entities** with an ID and a type, such as `Product` or `BlogPost`. The data is attached as **entity components**, for example `base`, `media` or `prices`. A page only requests the components it actually renders.

Five handler types work together: **queries** return entity IDs (with query templates for the Studio preview), **component resolvers** load the components for them, **links** connect entities such as a product and its variants, **actions** perform changes such as "add to cart", and **page indexes** list the concrete pages behind a dynamic page type.

Because every data source contributes its own resolvers, a product can get master data from the commerce system and prices from the ERP. Sections are unaffected; switching backends only swaps the resolvers. **Tokens** are the contracts through which Orchestr knows which app answers what. Orchestr caches queries, links and resolvers, and backend credentials stay on the server.

## Step by step

1. 1 ### Step 1: Choose or define a token

   Use the canonical tokens from `@laioutr-core/canonical-types` for standard cases. New data comes from a custom component token defined with `defineEntityComponentToken` and a Zod schema.
2. 2 ### Step 2: Create handlers

   Create handlers as files under `src/runtime/server/orchestr/`, such as `product/by-slug.query.ts`, `cart/add-item.action.ts` or `menu/base.resolver.ts`. Orchestr discovers them via `orchestrDirs`.
3. 3 ### Step 3: Check in the Request Editor

   Open the DevTools **Orchestr Request Editor** in the playground and run queries and actions with test input.

## Frequently asked questions

How does Orchestr differ from GraphQL?

Both request only the fields that are needed. Orchestr, however, runs only on the server, in TypeScript without its own query language. There are no request waterfalls in the browser, and backend credentials stay hidden.

What happens when the commerce system changes?

The new app provides resolvers for the same tokens. Sections and pages stay unchanged, because they only know canonical entities and components.

What information does every handler receive?

Every handler receives `clientEnv` with market, language, currency and whether the request is a content preview.

## Related

- [Build and release a first custom app](https://academy.laioutr.com/en/artikel/build-and-release-a-first-custom-app)20 min

  A custom app starts from the App Starter: set the package name, register Sections, Blocks or Orchestr handlers with registerLaioutrApp and test them in the playground. npm publish and laioutr app release then bring the version to Cockpit, and an environment's next deployment rolls it out.
- [Performance: caching and Orchestr](https://academy.laioutr.com/en/artikel/performance-caching-and-orchestr)6 min

  Laioutr speeds up storefronts with three cache layers: the Orchestr entity cache on the server, the HTTP cache at the edge and a store in the browser. Together they keep repeated requests from putting load on backends.
- [Fill sections with shop data](https://academy.laioutr.com/en/artikel/fill-sections-with-shop-data)7 min

  Sections with a data field show products, categories or posts from connected systems. The team picks a data query in Studio, sets input, limit and sorting, and Orchestr delivers the data at render time.
- [Declare content collections in code](https://academy.laioutr.com/en/artikel/declare-content-collections-in-code)15 min

  The project defines which content types the Laioutr CMS manages in the collections option of @laioutr-app/cms. After the next deployment, the types appear in Cockpit under Content, and their entries answer Orchestr queries like any other backend.

## Learn it in a lesson

- [Orchestr: entities, queries, actions](https://academy.laioutr.com/en/lektionen/developer-orchestr-and-data-queries)14 min

## [Developer start](https://academy.laioutr.com/en/leitfaeden/developer-start)

Search this guide

1. [Set up a local development environment](https://academy.laioutr.com/en/artikel/set-up-a-local-development-environment)15 min
2. [The Laioutr CLI: commands and authentication](https://academy.laioutr.com/en/artikel/laioutr-cli-commands-and-authentication)6 min
3. [Build and release a first custom app](https://academy.laioutr.com/en/artikel/build-and-release-a-first-custom-app)20 min
4. [Define custom Sections and Blocks for Studio](https://academy.laioutr.com/en/artikel/define-custom-sections-and-blocks-for-studio)15 min
5. [Orchestr: entities, queries, actions and resolvers](https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers)8 min
6. [Declare content collections in code](https://academy.laioutr.com/en/artikel/declare-content-collections-in-code)15 min
7. [Performance and technical SEO in code](https://academy.laioutr.com/en/artikel/performance-and-technical-seo-in-code)10 min

## Structured Data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://academy.laioutr.com/#website",
      "@type": "WebSite",
      "inLanguage": "en",
      "name": "Default",
      "url": "https://academy.laioutr.com/",
      "translationOfWork": {
        "@id": "https://academy.laioutr.com/#website"
      }
    },
    {
      "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#webpage",
      "name": "Academy Article",
      "url": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers",
      "@type": [
        "WebPage",
        "FAQPage"
      ],
      "breadcrumb": {
        "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#breadcrumb"
      },
      "isPartOf": {
        "@id": "https://academy.laioutr.com/#website"
      },
      "mainEntity": [
        {
          "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#/schema/question/1"
        },
        {
          "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#/schema/question/2"
        },
        {
          "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#/schema/question/3"
        }
      ],
      "potentialAction": [
        {
          "@type": "ReadAction",
          "target": [
            "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers"
          ]
        }
      ]
    },
    {
      "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#breadcrumb",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "name": "Home",
          "item": "https://academy.laioutr.com/en",
          "position": 1
        },
        {
          "@type": "ListItem",
          "name": "For developers",
          "item": "https://academy.laioutr.com/en/bereiche/for-developers",
          "position": 2
        },
        {
          "@type": "ListItem",
          "name": "Developer start",
          "item": "https://academy.laioutr.com/en/leitfaeden/developer-start",
          "position": 3
        },
        {
          "@type": "ListItem",
          "name": "Orchestr: entities, queries, actions and resolvers",
          "item": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers",
          "position": 4
        }
      ]
    },
    {
      "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#/schema/question/1",
      "@type": "Question",
      "inLanguage": "en",
      "name": "How does Orchestr differ from GraphQL?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "<p>Both request only the fields that are needed. Orchestr, however, runs only on the server, in TypeScript without its own query language. There are no request waterfalls in the browser, and backend credentials stay hidden.</p>"
      }
    },
    {
      "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#/schema/question/2",
      "@type": "Question",
      "inLanguage": "en",
      "name": "What happens when the commerce system changes?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "<p>The new app provides resolvers for the same tokens. Sections and pages stay unchanged, because they only know canonical entities and components.</p>"
      }
    },
    {
      "@id": "https://academy.laioutr.com/en/artikel/orchestr-entities-queries-actions-and-resolvers#/schema/question/3",
      "@type": "Question",
      "inLanguage": "en",
      "name": "What information does every handler receive?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "<p>Every handler receives <code>clientEnv</code> with market, language, currency and whether the request is a content preview.</p>"
      }
    }
  ]
}
```
