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

On this page