Validation Pipe
validatorPipe(opts?) is the main entry point in @atscript/moost-validator.
It checks a handler argument's runtime type. If that type is an Atscript annotated type, it runs the model's validator before your handler executes.
The Most Common Setup
Register it globally:
import { Moost } from 'moost'
import { validatorPipe } from '@atscript/moost-validator'
const app = new Moost()
app.applyGlobalPipes(validatorPipe())That is the best default for most apps.
Validate Request Bodies
This is the most common use case:
import { Controller } from 'moost'
import { Body, Post } from '@moostjs/event-http'
import { CreateUserDto } from './create-user.dto.as'
@Controller('users')
export class UsersController {
@Post()
async create(@Body() dto: CreateUserDto) {
// dto has already been validated
return this.users.create(dto)
}
}If validation fails, the pipe throws ValidatorError. For HTTP apps, pair it with Error Handling.
Validate PATCH Payloads
For partial updates, pass Atscript validator options to the pipe:
import { Controller } from 'moost'
import { Patch, Body } from '@moostjs/event-http'
import { UseValidatorPipe } from '@atscript/moost-validator'
import { UpdateUserDto } from './update-user.dto.as'
@Controller('users')
export class UsersController {
@Patch(':id')
@UseValidatorPipe({ partial: true })
async patch(@Body() dto: UpdateUserDto) {
return this.users.patch(dto)
}
}Use partial: 'deep' when nested objects should also allow missing fields.
Strip Unknown Properties
This is useful for request bodies that may contain extra fields:
app.applyGlobalPipes(
validatorPipe({
unknownProps: 'strip',
})
)Options:
'error'— reject unknown props'ignore'— keep them'strip'— remove them from the value
Apply It Per Controller Or Handler
Global registration is usually best, but the decorator form is useful when only part of the app uses Atscript DTOs.
Per Controller
import { Controller } from 'moost'
import { UseValidatorPipe } from '@atscript/moost-validator'
@UseValidatorPipe()
@Controller('users')
export class UsersController {}Per Handler
import { Controller } from 'moost'
import { Body, Post } from '@moostjs/event-http'
import { UseValidatorPipe } from '@atscript/moost-validator'
import { CreateUserDto } from './create-user.dto.as'
@Controller('users')
export class UsersController {
@Post()
@UseValidatorPipe()
async create(@Body() dto: CreateUserDto) {}
}UseValidatorPipe(opts?) is sugar for @Pipe(validatorPipe(opts)).
Validate Params And Query Values Carefully
The pipe validates the value it receives. It does not coerce strings into numbers, booleans, or dates.
That means:
- body payloads are usually a good fit because JSON parsing already gives you numbers, booleans, arrays, and objects
- raw HTTP params and query values are often strings, so string-based Atscript types fit best there
Good example:
export type EmailQuery = string.emailimport { Controller } from 'moost'
import { Get, Query } from '@moostjs/event-http'
import { EmailQuery } from './queries.as'
@Controller('users')
export class UsersController {
@Get('search')
async search(@Query('email') email: EmailQuery) {
return this.users.searchByEmail(email)
}
}If a param or query needs numeric validation, parse it before it reaches this pipe or validate it as a string-shaped contract instead.
Use Reusable Validated Primitive Types
This is one of the nicest patterns in Atscript + Moost.
Define a validated primitive once:
export type Email = string.emailThen use those types directly in handlers:
import { Controller } from 'moost'
import { Body, Post } from '@moostjs/event-http'
import { Email } from './types.as'
@Controller('newsletter')
export class NewsletterController {
@Post('subscribe')
async subscribe(@Body() email: Email) {
return this.newsletter.subscribe(email)
}
}That is hard to model with class-validator, because its validation model is centered on decorated classes and their properties. Atscript validates the type itself, so standalone reusable primitives work naturally.
Options At A Glance
validatorPipe(opts?) accepts the same Partial<TValidatorOptions> object as Atscript's runtime validator.
Most useful options:
partialunknownPropserrorLimitskipListreplaceplugins
If you already know the TypeScript validator API, the same options work here. See Validation Reference for the full low-level option details.
Beyond HTTP
The pipe is not tied to HTTP. It works anywhere Moost resolves handler arguments.
What is HTTP-specific is the built-in error transform, because that part returns HttpError(400).
Next Steps
- Error Handling — convert
ValidatorErrorinto HTTP responses - Validation Guide — deeper validator behavior and options
- Why Atscript In Moost? — when this package is the right fit