-API Query Strings and Caching with Orchex

This blog post contains information about using JavaScript to determine values for query string parameters for webservice API processors with the Orchex enterprise orchestration engine along with some details about processor stages and caching processor output.

Update 15.Dec.2025: After years of frustration with WordPress, I am finally abandoning this blog. The content will likely stay here for some time, but new content will appear here:

A previous post described processors for retrieving entries from the Kontent.ai content management system:

When you use its webservice API to retrieve an item (entry) from Kontent.ai, you can add a depth query string parameter to specify how many levels of references from item-to-item Kontent.ai follows to embed additional entries in what Kontent.ai refers to as modular content that appears with the primary requested item. The version described in that previous post hard-codes the depth query string parameter used by the Kontent.ai API. The version described in this post uses JavaScript to determine the value of that query string parameter. Specifically, if the HTTP request to invoke the orchestration process includes the depth query string parameter, this version uses that value. If that query string parameter is not present, then it uses any depth value passed in the body of the HTTP request. If no such value appears in the body, it defaults depth to 1.

First, we can reduce the template for Kontent.ai APIs to make it more reusable. I’ve also given it a new ID (which, with the file provider, means a new file – where dashes translate to slashes).

Update: This JSON fragment is obsolete. All properties relevant to webservice APIs have moved under a root webapi key.

{
  "key": "demo-kontent-template",
  "method": {
    "block_type": "literal",
    "content": "GET"
  },
  "protocol": {
    "block_type": "literal",
    "content": "https"
  },
  "domain": {
    "block_type": "literal",
    "content": "deliver.kontent.ai"
  },
  "rootpath": {
    "block_type": "js_inline",
    "content": "result = '/' + get_setting('kontent_id');"
    }
}

./json/processors/demo/kontent/template.json

Varying the depth parameter requires that we change caching criteria for the processor. Previously, we could cache by code_name alone, but as the processor now generates different output depending on the depth, we need to add that to the cache key as well. And we should also vary output depending on whether Orchex debug is enabled. In order to test caching, we need to enable caching even when debugging. We will restrict who can use these features in production, but in development we can pass verbose, debug, and disable_caching.

Two stages of the processor now use the same value: caching criteria include the depth value used by the Kontent.ai webservice API. To write the JavaScript, we need to think about the order in which orchestration processes occur. The JSON does not necessarily reflect the order in which the stages occur.

Orchex checks the cache relatively early in the process, before calling the webservice API. As caching varies by depth, the JavaScript that defines the cache key that depends on depth runs before the logic for the webservice API call that also determines depth. Therefore, the logic that determines the depth query string parameter for the Kontent.ai webservice API can reuse the depth variable set by the script that determines the caching key. If these stages occurred in the opposite order, then the query string parameter logic would define depth, and caching could use that value. I’m leaving in a libraries block I use for testing, in this case using the function that reformats the item.

{
    "key":"demo-kontent-item",
    "inherits":"demo-kontent-template",
    "libraries": [
        {
            "block_type": "js_url",
            "content": "http://127.0.0.1:3030/js/kontent.js",
            "cacheable": true
        }
    ],
    "cachingoptions": {
        "cacheable": true,
        "cache_key_script": "  

depth = orchex_context.http_request_info.query_params.depth 
    ? parseInt(orchex_context.http_request_info.query_params.depth) 
    : orchex_context.http_request_info.json_body.depth 
    ? orchex_context.http_request_info.json_body.depth 
    : 1;
    
result = {'payload': orchex_payload, 'depth': depth, 'debug': orchex_context.debug };

    "},
    "path": {
        "block_type": "js_inline",
        "content": "result = '/items/' + orchex_payload.code_name"
    },
    "qs": [
    {
        "name": "depth",
        "logic_block": {
            "block_type": "js_inline",
            "content": "result = depth;"
        }
    }
    ],
    "postrunscript": {
        "block_type": "js_inline",
        "content": "   

if ('error_code' in orchex_response) {
    result = orchex_response;
} else {
    response = {
        item: {
            elements: extractElements(orchex_response.item.elements),
        },

        modular_content: processModularContent(orchex_response.modular_content),
    };

    if (orchex_context.debug) {
        response.orchex = { context: orchex_context };
    }

    result = response;
}

    "}
}

./json/processors/demo/kontent/item.json

Now we can invoke it:

time curl -X POST http://127.0.0.1:3030/processors/demo-kontent-item/invoke?depth=3 -H "Content-Type: application/json" -d '{"orchex": {"debug": true, "verbose": true, "disable_caching": false}, "code_name": "home", "depth":2}' | jq | batcat -l json

Monitoring the server with debug mode enabled, we can see some wasteful passing of unused function definitions from the library specified in the processor definition to the quick_js JavaScript virtual machine currently in use, which apparently requires that we define any functions in the individual calls from Rust that use them.

First, with the query string parameter in the URL – see the 3 at the end:

Then, without the depth query string parameter, but with depth in the payload – now 2:

time curl -X POST http://127.0.0.1:3030/processors/demo-kontent-item/invoke -H "Content-Type: application/json" -d '{"orchex": {"debug": true, "verbose": true, "disable_caching": false}, "code_name": "home", "depth":2}' | jq | batcat -l json

Then, after removing the depth key from the payload:

time curl -X POST http://127.0.0.1:3030/processors/demo-kontent-item/invoke?depth=3 -H "Content-Type: application/json" -d '{"orchex": {"debug": true, "verbose": true, "disable_caching": false}, "code_name": "home"}' | jq | batcat -l json

We can also see the cache keys attempted.

Leave a comment