JSON DSL
Constructing JSON objects from SPARQL bindings using the JSON-WHERE extension.
Poliglot extends SPARQL with a JSON construction syntax. It builds JSON objects from script bindings, used for HTTP request bodies and UI component props.
Basic Syntax
PREFIX tasks: <https://example.org/spec/tasks#>
JSON {
"title": ?title,
"status": ?status
} WHERE {
?task a tasks:Task ;
tasks:title ?title ;
tasks:status ?status .
}The JSON block defines the output structure with variables as values. The WHERE block provides the SPARQL bindings. The result is a JSON string:
{ "title": "Review Q3", "status": "open" }Unbound Variables
Variables from OPTIONAL patterns that aren't bound are omitted from the output:
PREFIX tasks: <https://example.org/spec/tasks#>
JSON {
"title": ?title,
"description": ?desc,
"assignee": ?assignee
} WHERE {
?task tasks:title ?title .
OPTIONAL { ?task tasks:description ?desc }
OPTIONAL { ?task tasks:assignee ?assignee }
}If the task has no description, the output is {"title": "Review Q3", "assignee": "alice"}. The missing key is silently dropped.
Nested Arrays
Produce arrays with the [{ ... }] WHERE { ... } syntax inside the outer JSON block:
PREFIX tasks: <https://example.org/spec/tasks#>
JSON {
"name": ?projectName,
"tasks": [{
"title": ?title,
"status": ?status
}] WHERE {
?project tasks:hasTask ?task .
?task tasks:title ?title ;
tasks:status ?status .
}
} WHERE {
?project a tasks:Project ;
tasks:name ?projectName .
}The inner block has its own WHERE clause that iterates independently. This produces:
{
"name": "Q3 Planning",
"tasks": [
{ "title": "Review Q3", "status": "open" },
{ "title": "Ship v2", "status": "in-progress" }
]
}Static Values
Mix variables with static JSON:
PREFIX rars-ai: <https://poliglot.io/rars/spec/genai#>
JSON {
"model": ?model,
"max_tokens": ?maxTokens,
"messages": [
{
"role": "user",
"content": ?prompt
}
]
} WHERE {
?subject rars-ai:modelId ?model .
?payload rars-ai:prompt ?prompt .
OPTIONAL { ?payload rars-ai:maxTokens ?mt }
BIND(COALESCE(?mt, 4096) AS ?maxTokens)
}Static strings like "user" and numbers like 4096 pass through directly.
Where It's Used
The JSON DSL appears in two contexts in matrix specs:
rars-os:fromJSON in request templates, where ?_process is bound to the current execution:
tasks:CreateTaskBody
a rars-os:JSONFunction ;
rars-os:fromJSON """
PREFIX tasks: <https://example.org/spec/tasks#>
PREFIX rars-act: <https://poliglot.io/rars/spec/actions#>
PREFIX rars-os: <https://poliglot.io/rars/spec/os#>
JSON {
"title": ?title
} WHERE {
?_process rars-os:parent ?invocation .
?invocation rars-act:payload ?p .
?p tasks:title ?title .
}
""" .rars-os:json in UI props scripts, where ?subject is bound to the entity being rendered:
tasks:TaskCardProps
rars-ui:propsQuery [
rars-os:json """
PREFIX tasks: <https://example.org/spec/tasks#>
JSON {
"title": ?title,
"status": ?status
} WHERE {
?subject tasks:title ?title ;
tasks:status ?status .
}
"""
] .See RDF Functions for more on how these properties work.
See Also
- RDF Functions: rars-os:JSONFunction and the rars-os:fromJSON/rars-os:json properties
- Request Mapping: building HTTP request bodies
- Functions: SPARQL functions available in WHERE clauses