Skip to content

Pardon Scripting

This tutorial expands on Pardon scripting. Defining scripts and importing them into collections, as well as exporting them.

The exercies here requires that some products are created, if you haven’t created any, you can follow the Steps in the first exercise in the dataflow tutorial to make a few.

Scripts

Pardon scripts are javascript/typescript ECMA script modules (esm / esmodule). Consider our example service, we’ll be adding an example-helper.ts support script.

  • Directoryexample/
    • service.yaml
    • example-helper.ts
    • Directoryproducts/
      • list.https

We’ll have this script provide a “serviceToken”, using a slow connection to an authorization server with a timeout: and we are also appending a time-based value so we can see the result changing.

example/example-helper.ts
export async function serviceToken(env: string) {
await new Promise((resolve) => setTimeout(resolve, 700));
return `service-token-${env}-${`${Date.now()}`.slice(-5)}`
}

To use this script from an template expression, we’ll use export and import.

In order to import from ‘pardon:example’, as in

import { serviceToken } from 'pardon:example';

we need to define what the example collection exports. This is one line in the service.yaml:

example/service.yaml
export: ./example-helper.ts
config:
origin:
env:
prod: https://example.com
stage: https://stage.example.com
mixin:
- pardon:example/auth.mix.https

Feel free to experiment with the usual env=stage/env=prod changes, (notice that pardon takes a moment to update now.)

Loading Pardon Playground...

The imported scripts are loaded through the node-module import mechanism and may import other dependencies (including npm-installed packages).

pardon-in-pardon

We’ve got a new requirement, the business wants our ordering system to be available to the front-end, and we’ll need to do some validation:

The price of products change frequently, and when a customer places an order, the price on the screen might not match the price in the system: so we need to send the price-on-the-screen and check if it’s still correct.

That’s fair, but also totally annoying for the backend developers on the order system who have to add more data to every request and make sure it’s correct.

Well, pardon supports making pardon requests in scripts, and using the results in expressions. (We could techincally put this code in an expression, but it’s more readable to put non-trivial code in scripts).

To demonstrate this, first we need to define how to get this data from our products/get endpoint:

example/products/get.https
>>>
GET https://example.com/products/{{product}}
<<<
200 OK
{
"name": "{{?name}}",
"price": "{{?price}}"
}
Exercises
See what is returned in values.

Confirm the data extracted for products P1001, P1002, etc…

Loading Pardon Playground...

We have one more thing to fix, though. The price is per-unit but the cost needs to be the price multiplied by the quantity for each item.

Exercises
Assign quantities to order items

First let’s set some quantity on these products:

items=[
{ product: P1001, quantity: 15 },
{ product: P1003, quantity: 15 }
]

Notice the costs are not updated yet.

Loading Pardon Playground...

With this kind of scriptable data flow, we can use pardon to automate the toil of computing some fields so we focus on the data we care about.

(Remember we can always provide a cost value directly to skip the script.)

Next Steps

We’re ready to start descripting testcases and collection layering. Layering allows a base collection structure to be extended with team-specific mixins and defaults, allowing the use of an API to be described differently from the definition.

These next two sections are functionally independent, but pardon tests leverage collections and layering collections allows us to share collection layers and operational needs.