Database

Database

Every table gets a complete REST API the moment it exists.

Create a table and its API exists. There is nothing to generate, no route to write, and no schema to publish — the endpoints are derived from the table itself, so they cannot fall behind it.

A schema diagram showing tables as nodes and their foreign keys as connecting edges
The console reads your schema back to you, foreign keys included — this is derived from the database, not maintained by hand.

The five operations

Every table gets the same five, at the same shape:

MethodPathDoes
GET/{appUid}/autocrud/{table}List rows
POST/{appUid}/autocrud/{table}Create a row
GET/{appUid}/autocrud/{table}/{rowUid}Read one row
PATCH/{appUid}/autocrud/{table}/{rowUid}Update a row
DELETE/{appUid}/autocrud/{table}/{rowUid}Delete a row

None of them are reachable until a policy grants them. A new table is invisible until you say otherwise, which is the safe default.

Rows are named by uid

Every row has a uid, minted by the platform when the row is created, and that is the only handle the API speaks. The sequential id your table keys on stays inside the database: it is never returned, and a numeric id in a URL names nothing.

  • A create answers with the new row's uid.
  • A foreign key is presented under a _uid name holding the referenced row's uid: customer_id goes out as customer_uid, and a write sends customer_uid back.
  • org_id and tenant_id are set from the caller's scope and never appear in a request or a response.
  • Sending id, uid, a scope column or the raw customer_id is a 400 that names the field to send instead, never a silent drop.

One response envelope

Lists always return the same envelope, whether or not you paginate:

{
  "items": [ { "uid": "0199a3c2-7f1e-7b4a-9c3d-5e8f2a1b6c90", "subject": "Card declined" } ],
  "paging": { "limit": 25, "offset": 0, "count": 1, "total": 91 }
}

total is null unless you asked for it, because counting costs a second query.

What you cannot do over CRUD

Generated endpoints handle the ordinary cases well and deliberately stop there. Filtering is a single equality and sorting a single column — see Querying. Beyond that, write a handler or a custom action rather than pushing a query language through the URL.

Next

On this page