Developer GuidesGraph Operations

RDF Functions

Dynamic value resolution in matrix specifications through SPARQL functions, RDF functions, and filter functions.

Matrix specs are declarative: you define what resources exist, what actions do, and how requests are constructed. But some values can't be known at authoring time. A URL path depends on the subject's ID. An auth header depends on a resolved secret. A request body depends on the payload. RDF functions are the mechanism for declaring these dynamic values in your spec, to be resolved at runtime.

There are two categories of functions in the system: SPARQL functions that embed scripts to extract or construct values from the graph, and RDF functions that compose registered function implementations with parameter bindings. Both are declared in your Turtle spec and evaluated by RARS at runtime.

These functions are only supported in specific places in your spec. You cannot use them arbitrarily on any property.

SPARQL Functions

SPARQL functions embed a query directly in your spec. The query executes at runtime with ?_process bound to the current execution, giving it access to the invocation's subject, payload, and the full graph.

rars-os:ValueFunction

Extracts a single typed value using a SPARQL SELECT query. The query must bind a ?value variable. Used for dynamic paths, cache keys, graph URIs, and any place where a scalar value needs to be computed from graph state.

tasks:TaskIdPath
    a rars-os:ValueFunction ;
    rars-os:datatype xsd:string ;
    rars-os:fromValue """
    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#>
    SELECT ?value WHERE {
        ?_process rars-os:parent ?invocation .
        ?invocation rars-act:subject ?subject .
        ?subject tasks:externalId ?id .
        BIND(CONCAT("/api/tasks/", STR(?id)) AS ?value)
    }
    """ .

rars-os:datatype declares the expected return type: xsd:string, xsd:integer, xsd:boolean, xsd:anyURI, etc. The script navigates from ?_process through the invocation to reach subject and payload properties.

Supported contexts (these are the only places you can use rars-os:ValueFunction):

  • rars-act:requestObjectMap values: dynamic paths, headers, and other request template values
  • rars-act:resultGraph: dynamic named graph URIs for action result storage
  • rars-act:cacheKeyFunction: custom cache key derivation for action caching

rars-os:JSONFunction

Constructs a JSON object using JSON-WHERE syntax. The JSON block defines the output structure, the WHERE block provides SPARQL bindings. Used for HTTP request bodies and UI component props.

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,
        "status": ?status,
        "priority": ?priority
    } WHERE {
        ?_process rars-os:parent ?invocation .
        ?invocation rars-act:payload ?p .
        ?p tasks:title ?title .
        ?p tasks:status ?status .
        ?p tasks:priority ?priority .
    }
    """ .

Unbound variables (from OPTIONAL patterns) are omitted from the output. Nested arrays use the [{ ... }] WHERE { ... } syntax:

claude:ChatRequestBody
    a rars-os:JSONFunction ;
    rars-os:fromJSON """
    PREFIX rars-ai: <https://poliglot.io/rars/spec/genai#>
    PREFIX rars-act:   <https://poliglot.io/rars/spec/actions#>
    PREFIX rars-os:    <https://poliglot.io/rars/spec/os#>
    JSON {
        "model": ?model,
        "max_tokens": ?maxTokens,
        "messages": [{
            "role": ?role,
            "content": ?content
        }] WHERE {
            ?payload rars-ai:messages ?messageList .
            ?messageList rdf:rest*/rdf:first ?message .
            ?message rars-ai:role ?role ;
                     rars-ai:content ?content .
        }
    } WHERE {
        ?_process rars-os:parent ?invocation .
        ?invocation rars-act:subject ?subject ;
                    rars-act:payload ?payload .
        ?subject rars-ai:modelId ?model .
        OPTIONAL { ?payload rars-ai:maxTokens ?mt }
        BIND(COALESCE(?mt, 4096) AS ?maxTokens)
    }
    """ .

The inner JSON [...] block iterates over its own WHERE clause to produce an array.

Supported contexts (these are the only places you can use rars-os:JSONFunction):

  • rars-act:requestObjectMap with rars-http:body: HTTP request payloads in service integration request templates

rars-os:json (UI Props)

The same JSON-WHERE syntax is also used for UI component props via a different property. rars-os:json is declared on rars-ui:propsQuery and executes with ?subject bound to the entity being rendered (instead of ?_process):

tasks:TaskCard
    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 .
        }
        """
    ] .

Supported context:

  • rars-ui:propsQuery with rars-os:json: UI component props for renderables

RDF Functions

RDF functions don't embed SPARQL. Instead, they declare which registered function to call and what parameters to pass. They follow the Function Ontology (FnO) pattern and are evaluated during request template materialization.

rars-os:RDFFunction

tasks:ResolvedAPIKey
    a rars-os:RDFFunction ;
    rars-os:executesFunction rars-scrt:resolve_secret ;
    rars-os:functionInput [
        rars-os:functionParameter rars-scrt:secret ;
        rars-os:functionInputValue tasks:TaskServiceAPIKey
    ] .

rars-os:executesFunction points to a registered function (a fno:Function in the spec). rars-os:functionInput provides parameter bindings, each with a rars-os:functionParameter (the parameter's predicate URI) and rars-os:functionInputValue (the value to pass).

Composition

RDF functions compose by nesting. The inner function evaluates first, and its result becomes the input to the outer function:

tasks:BearerAuthHeader
    a rars-os:RDFFunction ;
    rars-os:executesFunction grel:string_concat ;
    rars-os:functionInput [
        rars-os:functionParameter grel:valueParameter ;
        rars-os:functionInputValue "Bearer "
    ] ;
    rars-os:functionInput [
        rars-os:functionParameter grel:valueParameter2 ;
        rars-os:functionInputValue [
            a rars-os:RDFFunction ;
            rars-os:executesFunction rars-scrt:resolve_secret ;
            rars-os:functionInput [
                rars-os:functionParameter rars-scrt:secret ;
                rars-os:functionInputValue tasks:TaskServiceAPIKey
            ]
        ]
    ] .

This evaluates bottom-up: resolve the secret, then concatenate "Bearer " with the result.

Available Functions

RDF functions reference registered implementations. The system provides:

Secret resolution:

- rars-scrt:resolve_secretrars-scrt:resolve_secret: resolves a secret URI to a marker string, replaced with the actual value at HTTP request time

  • rars-scrt:resolve_secret: resolves a secret URI to a marker string, replaced with the actual value at HTTP request time

String functions (from the GREL libraryGREL library): String functions (from the GREL library):

  • grel:string_concat, grel:string_replace, grel:string_substring, grel:string_split, grel:string_trim
  • grel:string_contains, grel:string_startsWith, grel:string_endsWith, grel:string_length
  • grel:toLowerCase, grel:toUpperCase, grel:string_toString, grel:string_toNumber

Math functions:

  • grel:math_abs, grel:math_ceil, grel:math_floor, grel:math_round

Boolean functions:

  • grel:boolean_and, grel:boolean_or, grel:boolean_not

Array functions:

  • grel:array_join, grel:array_get

Supported contexts (these are the only places you can use rars-os:RDFFunction):

  • rars-act:requestObjectMap values: auth headers, computed values in request templates
  • rml:functionMap: value transformation in response mapping POMs

Choosing the Right Function Type

SituationUse
Need a single typed value from the graphrars-os:ValueFunction with rars-os:fromValue
Need a JSON object from graph datarars-os:JSONFunction with rars-os:fromJSON
Need to call a registered function with parametersrars-os:RDFFunction with rars-os:executesFunction
Need to compose multiple registered functionsNested rars-os:RDFFunction

See Also

On this page