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 controllers. On the initial run, or when the change is detected, it makes an HTTP request to the Next.js dev server endpoint _schema_ of a corresponding segment, that is exposed when process.env.NODE_ENV is set to development. The endpoint returns schema for the corresponding segment, 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 this:

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

As you can see, the emited files follow recursive structure of the segments, and a segment foo/bar/baz will have a file .vovk-schema/foo/bar/baz.json. The root segment as the only exception from the rule is represented by root.json file.

The _meta.json file contains additional metadata, such as explicitly emitted fields of the vovk.config file using config key and some other information, having loose format, free to be extended.

When Vovk CLI reads these files, it builds a single object (called β€œfull schema”) 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.

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 for the current segment.

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, "$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. "openapi": { "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