Skip to content

Recipe - validate a request ​

Goal: reject bad input before any block runs, with a ready-made 400.

Use the route's request schemas first. bodySchema, querySchema and paramsSchema are set with save_route. They check types, required fields, ranges, formats and enums, and answer a failure with a 400 before the canvas starts. Do not write regex or if checks in a JS Runner for rules the schema can express. Write your own check only for rules the schema cannot, and put that check in the schema too (step 3).

The full field and rule tables are in the Route reference.

1. Describe the input ​

Example: POST /signup needs a valid email and an age from 18 to 120.

Call save_route:

json
{
  "routeId": "<route id>",
  "bodySchema": {
    "dataType": "object",
    "properties": [
      { "key": "email", "dataType": "str", "required": true,
        "rules": [{ "type": "format", "value": "email", "message": "Enter a valid email" }] },
      { "key": "age", "dataType": "int", "required": true,
        "rules": [{ "type": "min", "value": 18 }, { "type": "max", "value": 120 }] },
      { "key": "newsletter", "dataType": "bool", "required": false, "default": false }
    ]
  }
}

(On create, pass projectId, name, path and method as well.)

Pick the built-in way for each need:

NeedUse
Required or optional, default valuerequired, default (a default needs required: false)
Number rangeint or float with min and max rules
Text lengthstr with minLength, maxLength
Email, URL, UUID, IP, ISO date-timestr with a format rule: email, url, uuidv4, uuidv7, ipv4, ipv6, datetime
A text patternstr with a regex, startsWith, endsWith, contains or notContains rule
One of a fixed listenum with a values rule
List size, list of itemsarr with items and minItems or maxItems
Nested objectobject with properties
Uploaded filefile or blob with maxSize, minSize, mimeTypes

Query values and path params arrive as text, and are converted, so "25" passes int. A JSON body is strict: 5 is not "5". Keys you do not declare are kept, not rejected.

Query and path:

json
{
  "querySchema": { "dataType": "object", "properties": [
    { "key": "page", "dataType": "int", "required": false, "default": 1,
      "rules": [{ "type": "min", "value": 1 }] }
  ] },
  "paramsSchema": { "dataType": "object", "properties": [
    { "key": "id", "dataType": "int", "required": true }
  ] }
}

A path with :id needs a paramsSchema with exactly those keys.

2. See the failure ​

Call call_route with bad input:

json
{ "routeId": "<route id>", "body": { "email": "nope", "age": 12 } }

The route answers 400 and no block runs:

json
{
  "status": 400,
  "body": {
    "message": "Body validation failed",
    "errors": [
      { "path": "email", "property": "email", "errors": ["Enter a valid email"] },
      { "path": "age", "property": "age", "errors": ["<built-in text for min 18>"] }
    ]
  }
}

The message is Query validation failed for the query and Path parameters validation failed for path params. Built-in error texts come from the validator. Only string rules (str) take a message to replace them.

Then call it with good input and expect your canvas to run.

3. A rule the schema cannot express ​

Set a property's dataType to js and put the check in its js field. The code is the body of a function: input is the field's value. Return true to pass, or throw a ValidationError for a custom message. Do not use the js: prefix: the field is already code.

json
{ "key": "code", "dataType": "js", "required": true,
  "js": "if (!input.startsWith('SALE')) {\n  throw new ValidationError({ code: 'INVALID_CODE', message: 'Discount codes must start with SALE' });\n}\nreturn true;" }
  • Returning a falsy value fails with Custom JS validation failed.
  • Whatever you pass to ValidationError is returned to the caller as that entry's errors.
  • A thrown ordinary error is reported with its message.
  • The code sees the same request helpers as other code, such as getHeader and getConfig. See Dynamic values and js: expressions.
  • It checks one field's value. To compare two fields, check the second in the canvas (an if block then a 400 response).

4. Keep it tested ​

Save a test suite with a bad-input case that expects status 400, and a good-input case. See Write and run a test suite.

Common problems ​

What you seeWhat to do
A JS Runner with a regex checks inputDelete it. Use a regex or format rule on the field.
400 on every callCheck required: fields are required unless required: false.
"25" fails on a JSON bodyA JSON body is strict. Send the number 25, or accept text with a str field.
Invalid body schema formatdataType is misspelled or properties is not a list. See the Route reference.

Released under the Apache License 2.0. Enterprise features are under the Fluxify Enterprise Edition License.