Skip to content

Pardon Schemas

Previously we covered Pardon’s templates, and that they are composed into schemas.

Here discuss the process of generating and/or applying a schema to a template and how that resolves to a new schema.

Schemas

In Pardon, the templates are not “text documents with templating” which are rendered independently of their context and parsed after-the-fact. (As a hall-of-shame example of this, consider the fragility of the helm chart {{- toYaml .Values.doc | indent 10}} syntax.)

Templates are treated as values with implict and contextual rules.

Pardon’s http/https template files

  • are parsed to an HTTP object, and
  • that template is then used to extend a base schema.

Schema Operations

A schema supports the following major operations:

  • match - merges the current schema with a template. The match operation has three submodes, configuring how arrays and patterns are handled.

    • mix - treats the template as an abstract schema, patterns are recognized and single element arrays are treated as schemas for the elements of the array (non-1-element arrays are treated as tuples)
    • mux - treats the template as a concrete schema, patterns are still recognized.
    • match - treats the template as a literal, patterns are not recognized.

    Matching can resolve values: when a value overlaps a pattern, the variables in the pattern can be resolved. Some values are not resolved at match time because they’re provided by executing (possibly asynchronous) scripts, these values would be evaluated when the schmea is rendered.

  • render - renders the schema into a resulting value, this is the first time pardon ever considers evaluating any script expressions in templated values. (there are multiple subtypes of render as well, like preview that avoids running scripts, but these don’t affect how the schema was constructed from templates, so they’re not important to cover here).

So, in essence, a schema is produced by matching templates and the “ask”ed request, and it can be rendered into a request object synthesized from all those resolved inputs and any evaluated scripts.

Scopes

Export Scope Paths

The following schema and match combination would produce no exported values since "a" is scoped to each element of the list.

{ list: [{
a: "{{a}}",
b: "{{b=a+1}}"
}] }
{ list: [{
a: 10
}, {
a: 20
}] }

In contrast the following schema would be able to export an items array from the top-level scope.

{ list: [{
a: "{{items.a}}",
b: "{{items.b=a+1}}"
}] }
{ list: [{
a: 10
}, {
a: 20
}] }
items=[
{ a=10, b=15 },
{ a=20, b=25 }
]