Skip to Content
Schema

Schema

The npm run dev command runs vovk dev together with next dev via concurrently . The first one watches for changes in modules folder, looking for updates of controller methods and their validation. On the initial run, or when a change has been detected, it makes an HTTP request to the Next.js dev server’s endpoint _schema_ of a corresponding segment, that is exposed only when process.env.NODE_ENV is set to development. The endpoint returns schema for the corresponding segment only, allowing to isolate emitted .json files from each other. This approach works even in Edge Runtime , since route.ts files don’t have to import Node.js modules such as fs.

Each segment emits back-end schema into an individual JSON file that in its turn is used to generate client-side RPC modules. If you have different areas of your application (e.g. root, admin, customer), each area will have its own JSON schema file.

For a segment structure like this:

      • route.ts (root segment /api/)
      • route.ts (admin segment /api/admin)
      • route.ts (customer segment /api/customer)
        • route.ts (static segment /api/customer/static for OpenAPI)

The resulting schema files will be located in .vovk-schema/ directory like the following:

    • root.json
    • admin.json
    • customer.json
      • static.json
    • _meta.json

As you can see, the emited files follow recursive structure of the segments, so a segment foo/bar/baz will emit a schema file located at .vovk-schema/foo/bar/baz.json. The root segment as the only exception from this rule is represented by root.json file for nicer organization.

The _meta.json file contains additional metadata, such as explicitly emitted fields of the vovk.config file behind config key but also some other information.

When Vovk CLI reads these files, it builds a single object of keys segments and meta, where segments have flat structure of segment names as keys and their schema as values, and meta contains the _meta.json file content. This object is then used to generate client-side RPC modules, OpenAPI documentation, but also available on both client-side and server-side as schema export.

{ "segments": { "": { ... }, // root segment schema from root.json "admin": { ... }, // admin segment schema from admin.json "customer": { ... }, // customer segment schema from customer.json "customer/static": { ... } // static segment schema from customer/static.json }, "meta": { ... } // content of _meta.json file }
import { schema } from 'vovk-client'; // or import { schema } from 'vovk-client/schema'; // exports only the schema object, not the client-side RPC modules import type { VovkSchema, VovkSegmentSchema } from 'vovk'; console.log(schema satisfies VovkSchema); // schema for the admin segment console.log(schema.segments.admin satisfies VovkSegmentSchema); // schema for the admin segment

The schema is also available in the segmented client, containing schema with a single segment.

{ "segments": { "": { ... } // root segment schema from root.json }, "meta": { ... } // content of _meta.json file }
import { schema } from '@client/root'; // or import { schema } from '@client/root/schema';

Example of a segment schema file:

.vovk-schema/segments/foo.json
{ // Segment schema version "$schema": "https://vovk.dev/api/spec/v3/segment.json", // vovkInit function option that defines is the schema going to be emitted for this segment "emitSchema": true, // Segment name, for the root segment it's an empty string "segmentName": "foo", // List of controllers as key-value pairs for fast access // Key is a name of the variable that's going to be exported from "vovk-client" // Value is controller information "controllers": { "HelloRPC": { // RPC name that's going to be used in the client "rpcModuleName": "HelloRPC", // Original name of the controller class, used to determine segment name when the controller is changed on "vovk dev" "originalControllerName": "HelloController", // An argument of @prefix class decorator "prefix": "hello", // List of handlers as key-value pairs for fast access // Key is a static method name // Value is a handler information "handlers": { "getHello": { // Endpoint that's concatenated with the prefix "path": "greeting", // HTTP method "httpMethod": "POST", // Validation for "body", "query", "params", "output" and "iteration" // Can contain any custom data, at this case it's JSON schema emitted by "vovk-zod" "validation": { "body": { "type": "object", "properties": { "foo": { "type": "string" } }, "required": ["foo"], "additionalProperties": false, "x-isForm": true, // A vovk-specific field that indicates that the body is a FormData "$schema": "https://json-schema.org/draft/2020-12/schema" }, "query": { "type": "object", "properties": { "bar": { "type": "string" } }, "required": ["bar"], "additionalProperties": false, "$schema": "https://json-schema.org/draft/2020-12/schema" }, "params": { "type": "object", "properties": { "baz": { "type": "string" } }, "required": ["baz"], "additionalProperties": false, "$schema": "https://json-schema.org/draft/2020-12/schema" }, "output": { // or "iteration" for JSONLines response "type": "object", "properties": { "hello": { "type": "string" } }, "required": ["hello"], "additionalProperties": false, "$schema": "https://json-schema.org/draft/2020-12/schema" } }, // OpenAPI object that can be used to generate OpenAPI documentation, LLM tools, MCP etc. "operationObject": { "summary": "Hello world", "description": "Hello world", "x-tool-description": "Hello world" // custom description for an LLM tool }, // Custom data that can be defined by a custom decorator "misc": { "hello": "World" } } } } } }
Last updated on