@joystick.js/node

Input Validation

How to define and use input validation for getters and setters in Joystick apps.

Joystick uses a built-in validation library for validating inputs passed from the browser to the server as part of a call to a getter or setter.

Validation rules are defined using a nested object structure (written to mimic the structure of the data you're passing from the client) along with a few different properties to set the rules for your inputs.

Example Usage

Defining Validation on a Getter

api/books/getters.js

const getters = {
  books: {
    input: {
      category: {
        type: 'string',
        required: true,
      }
    },
    get: (input = {}, context = {}) => {
      return process.databases.mongodb.collection('books').find({
        user_id: context?.user?._id,
        category: input?.category,
      }).toArray();
    }
  }
};

export default getters;

Here, category is the name of the field we want to validate. We expect it to have a data type of string and require it to be passed in the input.

The object assigned to the field name (here, category) is known as the validator, while the properties on that object are known as the rules for that validator.

Before a getter or setter’s get() or set() method is executed, if present, the input they pass will be checked against the provided schema. If the input meets expectations, the request will proceed as normal.

In the event that the input of a client’s request fails validation, Joystick will return an HTTP 400 Bad Request status code.

Complex Validation Example

Validator objects can be composed together to create complex validation. For example, consider the following input validation schema:

Example Input Validation Schema

input: {
  name: {
    type: "string",
    required: true,
  },
  instruments: {
    type: "array",
    allowed_values: ["piano", "guitar", "vocals", "bass"],
  },
  albums: {
    type: "array",
    element: {
      type: "object",
      fields: {
        title: {
          type: "string",
          required: true,
        },
        year: {
          type: "string",
          optional: true,
        },
      },
    },
  },
},

This could be used to validate the following input:

Example Input

input: {
  name: "Trent Reznor",
  instruments: ["piano", "guitar", "vocals", "kazoo"],
  albums: [
    { title: 'The Downward Spiral', year: '1994' },
    { title: 'The Fragile', year: '1999' },
    { title: 'Broken EP', year: '1995' },
  ],
},

Above, we’d expect this input to fail validation as the instruments array on the input has a value that isn’t listed in the allowed_values array for that field in the schema.

While your data should be kept shallow for the sake of clarity and simplicity, Joystick’s validation can technically be nested infinitely as it runs recursively to an arbitrary depth.

API

Definition

input: {
  field_name: {
    type: string,
    required: boolean,
    optional: boolean,
    allowed_values: array,
    element: object,
    fields: object,
    min: number,
    max: number,
    regex: RegExp,
  }
}

Parameters

type string required
The expected type of data for the field. One of: any, array, boolean, float, integer, number, object, or string.
required boolean
Specifies whether or not a field is required. Defaults to false.
optional boolean
Alias for required: false. Specifies whether or not a field is optional.
allowed_values array
An array of allowed values for the field. Acts as an enum validator.
element object
Defines validation rules for the contents of an array. Only used when type is array.
fields object
Defines validation rules for the contents of an object. Only used when type is object.
min number
Sets a minimum numeric value for the field.
max number
Sets a maximum numeric value for the field.
regex RegExp
A regular expression used to validate the field value.