Skip to main content

Validation Decorators

Express-Cargo uses decorators to validate incoming request data that is bound to a class.

Validation is not performed by a standalone validate function. Instead, it is integrated into the bindingCargo middleware, which automatically validates data during the request lifecycle.

Built-in Validators

@min(value: number)

Checks if a number is greater than or equal to the specified minimum value.

  • value: The minimum allowed value.

@max(value: number)

Checks if a number is less than or equal to the specified maximum value.

  • value: The maximum allowed value.

@prefix(value: string)

Checks if a string starts with the specified prefix.

  • value: The required starting text.

@suffix(value: string)

Checks if a string ends with the specified suffix.

  • value: The required ending text.

@equal(value: any)

Validates that the input value is strictly equal (===) to the specified value.

  • value: The value to compare against.

@notEqual(value: any)

Validates that the input value is strictly not equal (!==) to the specified value.

  • value: The value to compare against.

Usage Example

Here is a complete example of how to use validation decorators within an Express application.

import express, { Request, Response, NextFunction } from 'express'
import { bindingCargo, getCargo, body, min, max, suffix, CargoValidationError } from 'express-cargo'

// 1. Define a class with source and validation rules
class CreateAssetRequest {
@body('name')
assetName!: string

@body('type')
@suffix('.png')
assetType!: string

@body('quantity')
@min(1)
@max(100)
quantity!: number
}

const app = express()
app.use(express.json())

// 2. Apply the bindingCargo middleware to a route
app.post('/assets', bindingCargo(CreateAssetRequest), (req: Request, res: Response) => {
// 3. If validation succeeds, access the data using getCargo
const assetData = getCargo<CreateAssetRequest>(req)
res.json({
message: 'Asset created successfully!',
data: assetData,
})
})

// 4. Add an error handling middleware to catch validation errors
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof CargoValidationError) {
res.status(400).json({
message: 'Validation Failed',
errors: err.errors.map(e => e.message),
})
} else {
next(err)
}
})

/*
To test this endpoint, send a POST request to /assets.

Example of a VALID request body:
{
"name": "My-Asset",
"type": "icon.png",
"quantity": 10
}

Example of an INVALID request body:
{
"name": "My-Asset",
"type": "icon.jpg", // Fails @suffix('.png')
"quantity": 101 // Fails @max(100)
}
*/

Error Handling

When validation fails, the bindingCargo middleware throws a CargoValidationError. You should register an Express error handling middleware to catch this error and format the response.

The CargoValidationError object has an errors property, which holds an array of CargoFieldError instances. Each CargoFieldError object contains a message property with a formatted string detailing the specific error (e.g., "quantity: quantity must be <= 100").

As shown in the code example, a common way to handle this is to map over the err.errors array to create a simple list of these error messages.

Example Error Response:

When the invalid request body from the example above is sent, the error handler will produce the following JSON response, which contains an array of formatted error messages.

{
"message": "Validation Failed",
"errors": [
"type: assetType must end with .png",
"quantity: quantity must be <= 100"
]
}