QUESTPIE
Build Your BackendRules

Validation

Field-level validation, Zod refinements, and custom validation rules.

QUESTPIE validates data at multiple levels: field constraints, Zod schemas, and custom validation hooks.

Field-Level Constraints

Built-in constraints on field definitions:

.fields(({ f }) => ({
  name: f.text(255).required(),
  email: f.email().required(),     // Validates email format
  website: f.url(),                       // Validates URL format
  rating: f.number().min(1).max(5),
  tags: f.text().array().maxItems(10),
}))
Chain MethodFieldsDescription
.required()AllField must have a value
.max(n)text, textareaMaximum string length
.min(n) / .max(n)numberNumeric range
.maxItems(n).array()Maximum array length
mimeTypesuploadAllowed file types (config)
maxSizeuploadMax file size in bytes (config)

These constraints are automatically enforced in the API validation layer (Zod schemas generated from field definitions).

Input Modifier

The .inputOptional() chain method controls how a field behaves during creation:

slug: f.text().required().inputOptional(),

This is useful for fields that are required in the database but computed by hooks (like slugs, reading times, etc.).

Custom Validation via Hooks

Use beforeValidate for custom validation logic:

.hooks({
  beforeValidate: async ({ data, operation }) => {
    if (operation === "create" && !data.slug) {
      data.slug = slugify(data.name);
    }
  },
})

For validation that should reject the operation, throw an error:

.hooks({
  beforeValidate: async ({ data }) => {
    if (data.scheduledAt && new Date(data.scheduledAt) < new Date()) {
      throw new Error("Cannot schedule appointments in the past");
    }
  },
})

On this page