Core Concepts & Features
Next.js App Router Back-End Framework
Vovk.ts is built on top of the Next.js App Router, utilizing Route Handlers as the underlying HTTP framework and being a thin abstraction layer over it, being fully compatible with existing Next.js features and libraries. It encourages the use of the Controller-Service-Repository pattern for organizing back-end code, leading to cleaner, more maintainable code for large applications.
export default class UserController {
@get('{id}')
static async getUser(req: NextRequest, { id }: { id: string }) {
// ...
}
}With the procedure function parameters, req.json(), req.nextUrl get typed automatically:
export default class UserController {
@get('{id}')
static getUser = procedure({
params: z.object({
id: z.string().uuid(),
}),
handle: async (req, { id }) => {
// ...
},
});
}Related Documentation
Back-end Segmentation
Vovk.ts utilizes Next.js routing capabilities to introduce an additional hierarchy level in the back-end called segments, powered by Next.js Route Handlers. Segments allow you to split the back-end into smaller, independently configured parts, each compiled into a separate serverless function.
// ...
const controllers = { UserRPC: UserController };
export type Controllers = typeof controllers;
export const { GET, POST } = initSegment({ controllers });Related Documentation
Schema Emission
Vovk.ts generates a comprehensive back-end schema in JSON format for each segment separately. This polarizing approach, usually opposed to contracts (schema implemented in a separate module that’s read by back-end and front-end), makes endpoint definition to be the only source of truth, enabling direct type mapping between back-end and front-end code (with CMD+Click you can navigate from the RPC method to the controller method), but also can expose custom data set by a decorator to the client side. Each segment emits its schema to an individual JSON file, located in .vovk-schema/ folder.
Related Documentation
Code Generation and “RPC Modules”
Controllers implemented as static classes are compiled into RPC modules through code generation. Each RPC module mirrors the controller’s structure but has a different argument signature, requiring three separate inputs: URL parameters, query parameters, and request body.
The code generation can be configured to emit either a single “composed” RPC client or multiple “segmented” RPC clients for each back-end segment independently, splitting the app into isolated parts that use their own schema files.
import { UserRPC } from 'vovk-client';
const user = await UserRPC.getUser({ params: { id: '123' } });Related Documentation
Deriving AI Tools
Vovk.ts can derive AI tools from back-end controllers (for same-context execution) and RPC modules (for HTTP calls), turning them into LLM function calling tools with name, description, parameters, and an execute function. This allows you to create AI agents that can interact with your back-end functionality seamlessly.
import { UserRPC } from 'vovk-client';
const { tools } = deriveTools({ modules: { UserRPC } });
console.log(tools); // { name, description, parameters, execute }Related Documentation
OpenAPI Mixins
Vovk.ts can convert OpenAPI 3.x schema files into API modules following that follow the same calling signature as Vovk.ts RPC modules. This allows you to mix Vovk.ts back-end functionality with third-party APIs defined in OpenAPI format and create derived AI tools that combine both - your back-end and external services.
import { PetStoreAPI } from 'vovk-client';
const pet = await PetStoreAPI.getPetById({ params: { petId: 1 } });Related Documentation
Documentation Generation and Publishing
Vovk.ts generates comprehensive documentation for RPC modules, including OpenAPI 3.1 documentation with code examples, compatible with Scalar , but also includes codegen templates for README and package files. This allows you to publish client libraries for TypeScript (using easily configured bundler), Python, and Rust with minimal effort.
import { UserRPC } from 'my-api-client';
const user = await UserRPC.getUser({ params: { id: '123' } });from my_api_client import UserRPC
params: UserRPC.GetUserParams = {"id": "123"}
user = UserRPC.get_user(params=params)use my_api_client::user_api::user_rpc::get_user;
use my_api_client::user_api::user_rpc::get_user_::params as Params;
let user = user_rpc::get_user(
(), // body
(), // query
Params {
id: String::from("123e4567-e89b-12d3-a456-426614174000")
},
None, // headers
None, // API root
false // disable client-side validation
).await?;Related Documentation
Vocabulary
- API Module - Generated module from a Vovk.ts controller or OpenAPI schema that exposes methods for making HTTP requests to the back-end.
- RPC Module - Generated module from a Vovk.ts controller, a subset term of API module that infer types directly from the controller methods.
- Controller - A class in Vovk.ts that defines HTTP endpoints using decorators. All methods in a controller declated with
statickeyword and decorated with HTTP method decorators are considered procedures. - Procedure - A static decorated method in a controller that handles HTTP requests. Procedure accepts
NextRequestobject and URL parameters and can be wrapped by procedure function for additional features like validation with automatic type inference. - Segment - A part of the back-end defined by a Next.js Optional Catch-All Segment that initializes controllers and is compiled into a separate serverless function.
- OpenAPI mixin - An API module generated from an OpenAPI 3.x schema file that can be used alongside Vovk.ts RPC modules.