<a id="queries"></a>

# Queries

Every data panel has one query. Its `type` chooses GraphQL, MagicQuery or Lua.
GraphQL documents live directly inside the query element; CDATA is useful when
XML escaping would obscure the document. The older nested GraphQL element is not
supported. GraphQL and Lua arguments bind declared state to input variables. Only
MagicQuery arguments accept literal `value` attributes; GraphQL literals belong
in the GraphQL document itself.

Use GraphQL when you need exact selections, aliases, variables or a query that
MagicQuery cannot express. Inspect the current directive-preserving schema before
writing it: entity names, IDs and mutation inputs are schema contracts.
A successful XML parse alone cannot prove that a tenant can execute a query.

MagicQuery is a concise way to request a supported noun and simple arguments.
It expands to a GraphQL query that is subject to the normal schema and permission
checks. Discover the current noun list with `listMagicQueries`: each entry includes its
`noun`, `kind`, `returnType`, `description` and accepted `parameters`. Do not assume
that an arbitrary GraphQL type is automatically a MagicQuery noun.

For a chosen noun, call `getMagicQuerySchema(query: ...)` to obtain its input JSON
Schema and output introspection. Call `getMagicQueryGraphQL(query: ...)` to inspect
the expanded `query` and `variables` without executing business reads. Its GraphQL
selection exposes the response root and any aliases to use in Workspace bindings;
the noun spelling alone does not define that root. The Workspace transport unwraps
the outer `magicQuery` envelope, so bind against the expanded operation's result.
Repeat discovery on each instance you publish to, because installed industry
modules can change the available nouns. Invalid nouns and parameters are rejected
when you save.

A Lua query names a declared read handler. Its input and output schemas are part
of the source contract. Read handlers cannot perform writes through the GraphQL
capability. Use an action handler, invoked by a mutation or form, for writes.

The [customer recipe](workspace-manual://workspace-xml-4/recipes) uses MagicQuery for its list and GraphQL for
editing. The KPI recipe uses a Lua read handler for its metric series. Those
examples show the exact supported argument and binding syntax.

The following authoring workspace runs all three discovery calls. Inspect the
generated operation to find its response root before binding a MagicQuery panel;
the output schema describes the record type, not the full connection envelope.

```xml
<workspace id="magicquery-discovery" title="MagicQuery discovery" role="Workspace author" xmlns:t="urn:cococo:dataxml">
  <panel id="discovery" title="Available queries and customer contract">
    <query type="graphql"><![CDATA[
      query MagicQueryDiscovery {
        nouns:listMagicQueries { noun kind description }
        contract:getMagicQuerySchema(query:"customers") { noun inputSchema outputSchema }
        operation:getMagicQueryGraphQL(query:"customers?limit=5") { query variables }
      }
    ]]></query>
    <record-table id="nouns" t:for="nouns" t:as="noun">
      <column label="Noun" t:value="noun.noun"/>
      <column label="Kind" t:value="noun.kind"/>
      <column label="Description" t:value="noun.description"/>
    </record-table>
    <text id="inputs" title="Accepted customer arguments" t:text="contract.inputSchema"/>
    <text id="outputs" title="Customer output type" t:text="contract.outputSchema"/>
    <text id="operation" title="Generated read operation" t:text="operation.query"/>
    <text id="variables" title="Generated variables" t:text="operation.variables"/>
  </panel>
</workspace>
```