Validating response data
The easiest setup for submitting response data is posting the response data as a JSON string to an endpoint. But, there is a risk involved when accepting JSON strings without validating them. How can you assure that the supplied structure is in the correct format and for the correct form? That's where response data validation comes into plan.
✅ Validation using the form data stencil
Tripetto contains a special feature to make it very easy to validate response data. To let this work, we need the so-called form data stencil. This is a unique hash that represents the format of the response data for a specific form. You can calculate this form data stencil from both the form definition and the response data. That makes it possible to compare the outcome of these calculations at a server endpoint without the need to perform in-depth validation of the JSON string itself.
To implement this, the endpoint should calculate (or know) the data stencil hash from the form definition. Please refer to the Form data stencil guide to learn how you can calculate the form data stencil at client- or server-side.
The next step is calculating the hash for each submitted response and then comparing the hashes. If the hashes are not equal, the data is not in the correct format, and the submission is invalid. The following example uses the calculateFingerprintAndStencil
and stencil
functions.
import { calculateFingerprintAndStencil, stencil } from "@tripetto/runner";
// Let's assume the exportables object is retrieved from the POST data
const exportables = req.body.exportables;
// Let's assume the definition is in this variable.
const definition = /* Definition goes here */;
// First calculate the stencil hash from the form definition
const formStencil = calculateFingerprintAndStencil(definition)?.stencil("exportables");
// Do we have a valid stencil hash from the form?
if (formStencil) {
// Then calculate the stencil hash from the data
const dataStencil = stencil("exportables", exportables);
// Compare it
if (formStencil === dataStencil) {
// The data is valid, continue processing it!
}
}
You could calculate the data stencil hash when a form definition changes and then store this hash together with the form definition. This saves a calculation step for each submission. As long as the form definition does not structurally change, the data stencil hash remains the same.
If you want to implement this validation in PHP, have a look at the code of the Tripetto WordPress plugin.
⚙️ Exportables vs. actionables
Tripetto supports two types of data collections that are retrieved from a form:
- Exportable data: These are all the fields in the form that are marked as exportable by the form creator;
- Actionable data: These fields are generated by action blocks that can perform certain actions like sending an email message.
Each type of data collection has its own data stencil hash. This is useful, for example, when you have a separate endpoint that handles the post-processing of actions. The following example shows how to generate the stencil hashes for the exportable and actionable data both from the form definition and the response data.
import { calculateFingerprintAndStencil, stencil } from "@tripetto/runner";
// Let's assume the exportables and actionables objects are retrieved from the POST data
const exportables = req.body.exportables;
const actionables = req.body.actionables;
// Let's assume the definition is in this variable.
const definition = /* Definition goes here */;
// Calculate the stencil hash from the form definition
const exportablesStencil = calculateFingerprintAndStencil(definition)?.stencil("exportables");
const actionablesStencil = calculateFingerprintAndStencil(definition)?.stencil("actionables");
// Calculate the stencil hash from the data
const exportablesStencil = stencil("exportables", exportables);
const actionablesStencil = stencil("actionables", actionables);
☑️ Static validation using JSON Schema
Using the available JSON Schemas for the IExportables
and IActionables
data objects, you can implement static validation using a JSON Schema validator. You need a validator for the language or framework you are using. For example, if you use Node.js you can use Ajv or Hyperjump to validate the response data.
There is a list of validators on the JSON Schema website.
Example
The following example shows how to set up validation using the JSON Schema.
- Ajv
- Hyperjump
// Make sure to install ajv first: `npm i ajv`
import Ajv from "ajv";
// Download the schema for the Tripetto Exportables object and make it available to your code
import tripettoExportablesSchema from "tripetto-exportables.schema.json";
const ajv = new Ajv({
validateSchema: false
});
const validate = ajv.compile(tripettoExportablesSchema);
// Now you can validate the response data
if (validate(/* Supply your exportables object here */)) {
// All good!
}
// Make sure to install Hyperjump first: `npm i @hyperjump/json-schema`
import JsonSchema from "@hyperjump/json-schema";
// Download the schema for the Tripetto Exportables object and make it available to your code
import tripettoExportablesSchema from "tripetto-exportables.schema.json";
JsonSchema.add(tripettoExportablesSchema);
const schema = awit JsonSchema.get("https://tripetto.com/sdk/tripetto-exportables.schema.json");
// Now you can validate the response data
const result = await JsonSchema.validate(
schema,
/* Supply your exportables object here */
);
if (result.valid) {
// All good!
}