Getting started
Vovk.ts as a back-end framework supports a wide range of validation libraries. The validation models are emitted as JSON Schemas in order to be used for validation on the client side (but also for code generation, OpenAPI spec and LLM Tools, etc).
Every validation library uses an internal withValidationLibrary
function that is used to wrap the controller handler, providing unified list of options and extending the handler with extra features. Each library is named as with[name]
where the name
is the name of the library, e.g. withZod
.
Options
import { z } from 'zod';
import { withZod } from 'vovk-zod';
import { prefix, post } from 'vovk';
@prefix('users')
export default class UserController {
@post('{id}')
static updateUser = withZod({
body: z.object({ /* ...*/ })
params: z.object({ /* ...*/ }),
query: z.object({ /* ...*/ }),
output: z.object({ /* ...*/ }), // in case of JSON response
// iteration: z.object({ /* ...*/ }), // in case of JSONLines response
// validateEachIteration: true, // for JSONLines response only
disableServerSideValidation: ['body', 'query'], // disable server-side validation for body and query
skipSchemaEmission: ['output'], // skip schema emission for output
isForm: false, // default
async handle(req, params) {
// ...
},
});
}
body
, query
and params
The body
, query
and params
options are used to specify input validation schemas. These schemas are used to validate the incoming request data before it reaches the controller handler.
output
and iteration
The output
and iteration
options are used to specify the output validation schemas, where output
is used for regular JSON responses and iteration
is used for JSONLines responses. Both are optional and they don’t affect the generated RPC modules typing, but recommended for enabling crutial features such as OpenAPI spec generation, Function Calling and Codegen for Python, Rust and other further clients. The output
and iteration
aren’t used for the client-side validation.
isForm
The isForm
option is used to specify whether the request body is a form data. This is useful for handling file uploads and other form-related data. Setting it to true
changes the RPC method typing to accept FormData
on the client side as body
option and adds x-isForm
field to the emitted JSON Schema for the body validation schema.
handle
The handle
is the controller handler function that will be executed after the validation is successful and return a response. It provides a type-flavoured NextRequest
, represented as VovkRequest<TBody, TQuery, TParams>
type as the first argument, and params: TParams
value as the second argument.
disableServerSideValidation
The disableServerSideValidation
option is used to disable the server-side validation for the specified validation library. It can be a boolean value that indicates whether to disable validation on the server-side completely, or an array of validation types (body
, query
, params
, output
, iteration
). This option does not affect type inference in the generated RPC modules, nor the client-side validation.
skipSchemaEmission
The skipSchemaEmission
option is used to skip the emission of the JSON Schemas for the handler, allowing to hide implementation details from the client-side code. It can be a boolean value that disables schema emission completely, or an array of validation types to skip schema emission for specific validation types (body
, query
, params
, output
, iteration
). This option does not affect type inference in the generated RPC modules but disables features that depend on the emitted schemas, including client-side validation.
validateEachIteration
The validateEachIteration
option is used exclusively for the iteration
validation schema. It indicates whether to validate each item in the iteration response, where by default it validates only the first iteration
item.
operation
An optional operation
object can be provided to specify OAS operation details for the method when @operation
decorator is not aplicable. Might be useful when using fn
on a normal function, not a class method.
Features
A handler created with withValidationLibrary
function gets some extra features that enhance its capabilities.
fn
The fn
property alllows to call the handler function directly, at the current context, without making an HTTP request. It follows similar signature as the generated RPC handler and accepts the same parameters.
const result = await UserController.updateUser.fn({
body: { /* ... */ },
query: { /* ... */ },
params: { /* ... */ },
meta: { /* ... */ },
disableClientSideValidation: false, // default
});
// same as
const result = await UserRPC.updateUser({
body: { /* ... */ },
query: { /* ... */ },
params: { /* ... */ },
meta: { /* ... */ },
disableClientSideValidation: false, // default
});
For more information about the fn
property, see the callable handlers page. Also check the meta documentation, since it’s handled differently in the fn
property and the RPC module.
schema
const schema = UserController.updateUser.schema;
// same as UserRPC.updateUser.schema
The schema
property provides the method schema for the handler, similar to the RPC method schema. It’s used in tendem with the fn
property to build function calling tools to call the handler by AI without making an HTTP request.
models
const bodyModel = UserController.updateUser.models.body;
The models
property is exclusive to the server-side methods. It allows to access the original validation models used in the handler.