Skip to Content
TechniquesValidation

Validation

Austial’s validation story leans entirely on FastAPI/pydantic — DTOs are just pydantic BaseModel classes, type-hinted as a handler’s = Body() parameter, exactly the shape you’d already reach for in plain FastAPI.

Defining a DTO

from pydantic import BaseModel class CreateCatDto(BaseModel): name: str class UpdateCatDto(BaseModel): name: str | None = None
@Post() async def create(self, dto: CreateCatDto = Body()) -> Cat: return self.service.create(dto)

FastAPI parses and validates the incoming JSON body against CreateCatDto before your handler is even called — a request missing name, or with the wrong type, never reaches create().

ValidationPipe

from austial.common.pipes import ValidationPipe app.use_global_pipes(ValidationPipe())

Registering ValidationPipe globally (as every austial new project does by default in src/main.py) ensures validation failures come back in the same error body shape as every other exception in the app:

{ "statusCode": 400, "message": ["field required: name"], "error": "Bad Request" }

See Pipes for the full PipeTransform reference if you need custom transformation/validation logic beyond what pydantic gives you for free.

Nested and reused DTOs

Because DTOs are plain pydantic models, everything pydantic supports — nested models, Field(...) constraints, custom validators, model_config — works exactly as it does in a plain FastAPI app:

from pydantic import BaseModel, Field class Address(BaseModel): street: str city: str class CreateCustomerDto(BaseModel): name: str = Field(min_length=1, max_length=100) address: Address

There’s no separate Austial-specific validation DSL to learn on top of this — the framework’s job stops at wiring pydantic’s own validation into the consistent error response format.

Last updated on