A server in ten lines
A UDC server is a directory of collections and a few lines that serve it. This one keeps three
books in memory; swap kind: memory for Postgres, a directory of files or an HTTP API later
without touching the server.
-
Install the server, the protocol package and Fastify:
Terminal window mkdir books-server && cd books-server && npm init -y && npm pkg set type=modulenpm install @jsudc/server @jsudc/core fastify zodnpm also installs
drizzle-ormandpg, the server’s other peers; a memory collection never opens a connection. -
Lay out one collection,
books:- server.ts
Directorycollections/
Directorybooks/
- schema.json the fields
- view.yaml how the data view shows it
- source.yaml where the rows live
- seed.json the rows a memory collection starts with
collections/books/schema.json {"version": "v1","core_fields": [],"fields": {"title": { "type": "string", "required": true },"author": { "type": "string" },"year": { "type": "integer", "min": 0 },"pages": { "type": "integer", "min": 1 },"read": { "type": "bool" }},"field_order": ["title", "author", "year", "pages", "read"]}collections/books/view.yaml default_renderer: tableavailable_renderers: [table, cards]search:fields: [title, author]columns:- { field: title, width: 260 }- { field: author, width: 200 }- { field: year, width: 90, align: right }- { field: pages, width: 90, align: right }- { field: read, width: 80, align: center }card_options:title_field: titlesubtitle_field: authorcollections/books/source.yaml kind: memorycollections/books/seed.json [{"title": "The Master and Margarita","author": "Mikhail Bulgakov","year": 1967,"pages": 384,"read": true},{"title": "The Bridge on the Drina","author": "Ivo Andrić","year": 1945,"pages": 314,"read": true},{"title": "Dictionary of the Khazars","author": "Milorad Pavić","year": 1984,"pages": 338,"read": false}] -
The server:
server.ts import { createDispatcher, loadRegistry, makeSource, udcPlugin } from "@jsudc/server";import Fastify from "fastify";const registry = loadRegistry("./collections", (asset, registry) =>makeSource(asset, { registry, env: process.env }),);const app = Fastify({ logger: true });const dispatcher = createDispatcher(registry, { log: app.log });await app.register(udcPlugin, { dispatcher, registry, swagger: false });await app.listen({ port: 5100 });loadRegistryreads every directory undercollections/, validates its three files and fails at start on a mistake;makeSourceturns eachsource.yamlinto its source.udcPluginmountsPOST /udc/<action>on your own Fastify instance. -
Run it and ask for the books:
Terminal window node server.tscurl -s localhost:5100/udc/list -H 'content-type: application/json' \-d '{"collection":"books","sort":[{"field":"year","dir":"asc"}]}'{"kind": "udc.list.ok","id": "","payload": {"rows": [{ "__meta": { "id": "…", "version": 1 }, "title": "The Bridge on the Drina", "year": 1945, … },…],"next_cursor": null,"total": 3}}
Every answer is HTTP 200; the envelope’s kind says ok or err. Try describe with
{"collection":"books"} to see what a client learns before it draws anything, or mutate to add
a fourth book: a memory collection keeps it until the process ends.
- The OpenAPI document of every action at
/docs: dropswagger: falseand install@fastify/swagger @fastify/swagger-ui fastify-type-provider-zod. - Draw the books: a React data view pointed at this server.
- Keep them in Postgres: the full stack.