The Schema API provides JSON Schema-based validation with automatic type inference for Feathers services.
schema
Creates a schema wrapper that provides validation and type inference from a JSON Schema definition.
import { schema } from '@feathersjs/schema'
const userSchema = schema({
$id: 'user',
type: 'object',
required: ['email', 'password'],
properties: {
email: { type: 'string' },
password: { type: 'string' },
age: { type: 'number' }
}
} as const)
Parameters
definition
JSONSchemaDefinition
required
JSON Schema definition object with $id property
Custom AJV validator instance. Defaults to the built-in validator with coerceTypes: true
Returns
Returns a SchemaWrapper<S> instance with the following members:
validate
<T>(data: T) => Promise<T>
Validates data against the schema. Returns validated (possibly coerced) data or throws BadRequest error
properties
Record<string, JSONSchema>
The schema’s property definitions
Array of required property names
The original schema definition
Type inference helper (TypeScript only). Use with Infer<typeof schema> to extract the inferred type
Types
JSONSchemaDefinition
Extends standard JSON Schema with required $id property:
type JSONSchemaDefinition = JSONSchema & {
$id: string
$async?: true
properties?: { [key: string]: JSONSchema }
required?: readonly string[]
}
Validator
A validation function type:
type Validator<T = any, R = T> = (data: T) => Promise<R>
Infer
Extract the TypeScript type from a schema:
import { Infer } from '@feathersjs/schema'
const mySchema = schema({ /* ... */ } as const)
type MyType = Infer<typeof mySchema>
Combine
Combine a schema type with additional properties:
import { Combine } from '@feathersjs/schema'
type UserWithId = Combine<typeof userSchema, { id: number }>
SchemaWrapper
The class returned by schema() that wraps a JSON Schema definition.
validate
Validates and coerces data according to the schema:
try {
const validated = await userSchema.validate({
email: '[email protected]',
password: 'secret',
age: '25' // Will be coerced to number
})
} catch (error) {
// BadRequest with validation errors
}
Returns: Promise<T> - Validated and coerced data
Throws: BadRequest - If validation fails
toJSON
Returns the underlying schema definition:
const definition = userSchema.toJSON()
DEFAULT_AJV
The default AJV instance used by schemas:
import { DEFAULT_AJV } from '@feathersjs/schema'
// Configuration:
// - coerceTypes: true
// - addUsedSchema: false
Add format validators to an AJV instance:
import { Ajv, addFormats } from '@feathersjs/schema'
const ajv = new Ajv()
addFormats(ajv, ['email', 'uri', 'date-time'])
const schema = schema(definition, ajv)
Parameters
AJV instance to add formats to
formats
FormatName[] | FormatsPluginOptions
Array of format names or configuration object
Example Usage
Basic Schema
import { schema, Infer } from '@feathersjs/schema'
const messageSchema = schema({
$id: 'message',
type: 'object',
required: ['text'],
additionalProperties: false,
properties: {
id: { type: 'number' },
text: { type: 'string' },
userId: { type: 'number' },
createdAt: { type: 'string', format: 'date-time' }
}
} as const)
type Message = Infer<typeof messageSchema>
Custom Validation
import { Ajv, schema, addFormats } from '@feathersjs/schema'
const ajv = new Ajv({
coerceTypes: true,
removeAdditional: true
})
addFormats(ajv, ['email', 'uri'])
const userSchema = schema({
$id: 'user',
type: 'object',
properties: {
email: { type: 'string', format: 'email' },
website: { type: 'string', format: 'uri' }
}
} as const, ajv)
With Service
import { schema, Infer } from '@feathersjs/schema'
import { hooks } from '@feathersjs/schema'
const userDataSchema = schema({
$id: 'user-data',
type: 'object',
required: ['email', 'password'],
properties: {
email: { type: 'string', format: 'email' },
password: { type: 'string', minLength: 8 }
}
} as const)
type UserData = Infer<typeof userDataSchema>
app.service('users').hooks({
before: {
create: [hooks.validateData(userDataSchema)]
}
})