Auto-generated REST API layer for ObjectStack — turns protocol metadata into CRUD, batch, metadata, and discovery endpoints with zero boilerplate.
@objectstack/rest is registered as a kernel plugin and emits HTTP routes for every object defined in the protocol metadata. The Hono framework adapter (@objectstack/hono) invokes these routes through HttpDispatcher from @objectstack/runtime.
pnpm add @objectstack/restimport { ObjectKernel } from '@objectstack/core';
import { createRestApiPlugin } from '@objectstack/rest';
const kernel = new ObjectKernel();
await kernel.use(createRestApiPlugin({
api: {
api: {
version: 'v1',
basePath: '/api',
},
},
}));
await kernel.bootstrap();import { RestServer } from '@objectstack/rest';
const server = new RestServer(httpServer, protocol, {
api: { version: 'v1', basePath: '/api' },
});
server.registerRoutes();import { RouteManager } from '@objectstack/rest';
const routes = new RouteManager(httpServer);
routes.register({
method: 'GET',
path: '/custom',
handler: async (req, res) => {
res.json({ ok: true });
},
});For every object Project defined in metadata, the plugin exposes:
| Method | Path | Purpose |
|---|---|---|
GET |
/api/v1/projects |
List with filter, sort, top, skip, select, groupBy, aggregations. |
GET |
/api/v1/projects/:id |
Single record (with ETag / Last-Modified). |
POST |
/api/v1/projects |
Create. |
PATCH |
/api/v1/projects/:id |
Partial update. |
PUT |
/api/v1/projects/:id |
Full replacement. |
DELETE |
/api/v1/projects/:id |
Delete. |
POST |
/api/v1/projects/createMany |
Batch create. |
POST |
/api/v1/projects/updateMany |
Batch update. |
POST |
/api/v1/projects/deleteMany |
Batch delete. |
POST |
/api/v1/projects/batch |
Mixed batch. |
Plus metadata and discovery routes:
| Path | Description |
|---|---|
/api/v1/meta |
All metadata types. |
/api/v1/meta/:type |
Objects, views, apps, flows, agents, tools, translations. |
/api/v1/meta/:type/:name |
Single metadata resource. |
/api/v1 and /.well-known/objectstack |
Discovery / service manifest. |
| Export | Kind | Description |
|---|---|---|
createRestApiPlugin(config) |
function | Kernel plugin factory. |
RestApiPluginConfig |
type | { api: { version, basePath }, ... }. |
RestServer |
class | Direct instantiation for adapters that need it. |
RouteManager, RouteGroupBuilder |
classes | Register and group custom routes. |
RouteEntry |
type | Route definition shape. |
| Option | Type | Default | Notes |
|---|---|---|---|
api.version |
string |
'v1' |
Embedded in the route prefix. |
api.basePath |
string |
'/api' |
Root path for the API. |
paths.pathTransform |
'plural' | 'kebab' | 'camel' |
'plural' |
Object → URL segment transform. |
caching.etag |
boolean |
true |
Emits ETag header. |
caching.lastModified |
boolean |
true |
Emits Last-Modified. |
| Variable | Values | Default | Notes |
|---|---|---|---|
OS_REST_LOG |
debug | info | warn | error | silent |
info |
Level for this package's own fault logging. |
OS_REST_LOG declares how loud the REST layer is about faults it reports
itself — the [REST] … lines written when a request fails. It is the same
vocabulary, and the same shipped default, as @objectstack/objectql's
OS_REGISTRY_LOG; an unrecognised value falls back to the default rather than
silencing anything.
At the default a reported fault prints the whole Error: its message, its
cause chain and its stack frames. That is deliberate and it is the reason to
leave it alone. When a 5xx is withheld from the client, the log is the only
place the underlying driver text exists, and that text travels on error.cause
— it is printed only because a whole Error, not a summary, reaches the
console. Lowering the level to error or silent discards diagnostics that
have no second copy anywhere.
⇒ Prefer declaring a quieter level in a test harness (vitest.config.ts's
env block) over exporting it for a running server.
- JSON envelope:
{ success, data, error?, meta? }. - Validation errors: HTTP 400 with Zod issue list.
- Auth/permission failures: HTTP 401/403 emitted by
@objectstack/plugin-authand@objectstack/plugin-security. If-None-Match/If-Modified-Sincehonored for GET.
- ✅ Every runtime that exposes ObjectStack data over HTTP.
- ❌ RPC-only or GraphQL-only deployments — use a custom
@objectstack/runtimeconsumer.
@objectstack/runtime—HttpDispatcherthat invokes routes.- Framework adapters under
packages/adapters/*.
- 📖 Docs: https://objectstack.ai/docs
- 📚 API Reference: https://objectstack.ai/docs/references/api
- 🤖 Skill:
skills/objectstack-api/SKILL.md
Apache-2.0. See LICENSING.md.