Collections
Typed typed CRUD with auto-scoped reads. Same expressive filter DSL on every SDK.
Collections are typed tables you define once per project and read/write from any SDK. Every read auto-scopes to the signed-in user — you never see another user's rows even if you forget to add a filter. Writes stamp the user from the session token; client-supplied user_id fields are ignored.
Define a collection's schema via the CLI (amba collections create <name> --field title:text --field body:text) or the admin API before reading or writing from a client SDK.
Quick start
Operations
Insert
The server stamps user_id from your session. Any user_id in the payload is rejected.
Find one
Returns null (or throws NotFound, depending on platform) if the row doesn't exist or doesn't belong to the signed-in user.
Find many
find returns { data, next_cursor, has_more }. The filter DSL composes expressive operators server-side.
Filter operators
| Operator | Web / Node / RN | Server semantics |
|---|---|---|
eq | where.eq('col', value) | = |
ne | where.ne('col', value) | <> |
gt | where.gt('col', value) | > |
gte | where.gte('col', value) | >= |
lt | where.lt('col', value) | < |
lte | where.lte('col', value) | <= |
in | where.in('col', [a, b, c]) | IN (...) |
notIn | where.notIn('col', [a, b, c]) | NOT IN (...) |
like | where.like('col', 'Hello%') | LIKE (case-sensitive) |
ilike | where.ilike('col', 'hello%') | ILIKE (case-insens.) |
isNull | where.isNull('col') | IS NULL |
isNotNull | where.isNotNull('col') | IS NOT NULL |
and | where.and(f1, f2, ...) | ... AND ... |
or | where.or(f1, f2, ...) | ... OR ... |
not | where.not(f) | NOT (...) |
Update
Update by id is the canonical shape. Bulk update (update many rows matching a filter) is exposed via the admin API; on the client SDK, iterate and update individually.
Delete
Soft delete — rows are marked deleted_at and excluded from subsequent reads. Hard delete is admin-only.
Patterns
Cursor pagination
For large collections, prefer cursor pagination over offset (it's stable under concurrent inserts and constant-cost per page):
Typed reads
Pass a generic to insert / findOne / find so the response is typed end-to-end:
React hook reactivity
useCollection re-fetches on mount, on options change, and on auth state change. Use refetch for manual refresh:
Limits
- Max page size: 500 rows per
findcall. Use cursor pagination for larger result sets. - Filter depth:
and/or/notcan nest up to 8 levels deep. - Row payload size: up to 1 MB per insert / update (JSON-encoded).
- Auto-scoping: client SDKs cannot read or write another user's rows. To act across users from a server context, use
amba.asUser(uid)(Node SDK) or the admin API. - Schema is define-once: schemas are managed via the CLI / admin API, not from client SDKs.
Reference
- Client API — collections — endpoint reference.
- CLI:
amba collections— schema management. - Auth feature — prerequisite.
- Per-platform quickstarts: Web, Node, iOS, Android, Flutter, Unity.