Core · Framework · Database

Repositories and data operations

Repository reads and writes logical Collection fields and relations, applying codecs, query contracts and bound policies. Obtaining one neither creates tables nor authenticates callers.

This page covers direct server-side database access. To call it from a client, declare Repository data APIs with defineRepositoryApiRoutes() and use api.repository(name). Database operations do not automatically become HTTP endpoints.

Single-record writes

This uses the order model and requires SO-001 to be absent. User-facing callers must first bind authorization-derived policies:

TypeScript
import type { DatabaseManager } from '@nocobase/db';

export async function createOrder(database: DatabaseManager) {
  const orders = database.repository('orders');
  const result = await orders.createOne({
    values: { orderNo: 'SO-001', title: 'First order', amount: '19.90' },
  });
  return result.record;
}

createOne(), updateOne() and upsertOne() return mutation results; read .record rather than treating the result as a row. Exact decimal strings avoid floating-point money errors.

Read/write contracts

MethodBehavior
findMany()Lazy query; await an array or iterate asynchronously
findOne()A record or undefined, without asserting uniqueness
count() / exists()Count or existence
updateOne() / deleteOne()Require exactly one target
upsertOne()Unique selector with separate create/update inputs
Bulk create/update/deleteCounts and optionally selected records

Do not mix awaiting and iteration, or repeatedly iterate one query. Bulk update/delete requires a filter or explicit all: true. Bulk values do not support all single-record nested relation operations.

Selection and authorization

Select only required fields. Omitting selection normally reads all scalars and must not expose sensitive fields. Apply server-derived row, field and relation policies with withPolicy(); mutation return reads are also governed by policy.

Caller-provided filters do not grant access. Validate fields, limits and complexity for external query input.

When to use Query

Use Query for set-based backfills or table queries Repository cannot express. It does not carry every Repository mapping or policy semantic, so handle naming and authorization explicitly. See Transactions and Association queries.

Interfaces and implementation

NocoBase docs assistant

Ask anything about NocoBase…

Each question is answered independently, without earlier questions or answers. Include all relevant context.