Collections

In NocoBase plugin development, Collection (data table) is one of the core concepts. You can add or modify data table structures in plugins by defining or extending Collections. Unlike data tables created through the "Data Source Management" interface, Collections defined in code are usually system-level metadata tables and won't appear in the data source management list.

Defining Data Tables

Following the conventional directory structure, Collection files should be placed in the ./src/server/collections directory. Use defineCollection() to create new tables and extendCollection() to extend existing tables.

import { defineCollection } from '@nocobase/database';

export default defineCollection({
  name: 'articles',
  title: 'Sample Articles',
  fields: [
    { type: 'string', name: 'title', interface: 'input', uiSchema: { title: 'Title', required: true } },
    { type: 'text', name: 'content', interface: 'textarea', uiSchema: { title: 'Content' } },
    {
      type: 'belongsTo',
      name: 'author',
      target: 'users',
      foreignKey: 'authorId',
      interface: 'recordPicker',
      uiSchema: { title: 'Author' },
    },
  ],
});

In the example above:

  • name: Table name (a table with the same name will be automatically generated in the database).
  • title: Display name of the table in the interface.
  • fields: Field collection, each field contains type, name, and other attributes.

When you need to add fields or modify configurations for other plugins' Collections, you can use extendCollection():

import { extendCollection } from '@nocobase/database';

export default extendCollection({
  name: 'articles',
  fields: [
    {
      type: 'boolean',
      name: 'isPublished',
      defaultValue: false,
    },
  ],
});

After activating the plugin, the system will automatically add the isPublished field to the existing articles table.

Tip

The conventional directory will complete loading before all plugins' load() methods execute, thus avoiding dependency issues caused by some data tables not being loaded.

Field Type Quick Reference

In defineCollection's fields, type determines the column type of the field in the database. Below are all built-in field types:

Text

typeDatabase TypeDescriptionSpecific Parameters
stringVARCHAR(255)Short textlength?: number (custom length), trim?: boolean
textTEXTLong textlength?: 'tiny' | 'medium' | 'long' (MySQL only)

Number

typeDatabase TypeDescriptionSpecific Parameters
integerINTEGERInteger--
bigIntBIGINTBig integer--
floatFLOATFloat--
doubleDOUBLEDouble precision float--
decimalDECIMAL(p,s)Fixed-point numberprecision: number, scale: number

Boolean

typeDatabase TypeDescription
booleanBOOLEANBoolean value

DateTime

typeDatabase TypeDescriptionSpecific Parameters
dateDATE(3)DateTime (with milliseconds)defaultToCurrentTime?, onUpdateToCurrentTime?
dateOnlyDATEONLYDate only, no time--
timeTIMETime only--
unixTimestampBIGINTUnix timestampaccuracy?: 'second' | 'millisecond'
Tip

date is the most commonly used date type. If you need to differentiate timezone handling, there are also datetimeTz (with timezone) and datetimeNoTz (without timezone) available.

Structured Data

typeDatabase TypeDescriptionSpecific Parameters
jsonJSON / JSONBJSON datajsonb?: boolean (use JSONB under PostgreSQL)
jsonbJSONB / JSONPrefer JSONB--
arrayARRAY / JSONArrayNative ARRAY type available under PostgreSQL

ID Generation

typeDatabase TypeDescriptionSpecific Parameters
uidVARCHAR(255)Auto-generated short IDprefix?: string
uuidUUIDUUID v4autoFill?: boolean (default true)
nanoidVARCHAR(255)NanoIDsize?: number (default 12), customAlphabet?: string
snowflakeIdBIGINTSnowflake IDautoFill?: boolean (default true)

Special Types

typeDatabase TypeDescription
passwordVARCHAR(255)Auto salted hash storage
virtualNo actual columnVirtual field, no column created in database
contextConfigurableAuto-populated from request context (e.g. currentUser.id)

Relation Types

Relation fields do not create database columns; instead, they establish inter-table relationships at the ORM layer:

typeDescriptionKey Parameters
belongsToMany-to-onetarget (target table), foreignKey (foreign key field)
hasOneOne-to-onetarget, foreignKey
hasManyOne-to-manytarget, foreignKey
belongsToManyMany-to-manytarget, through (junction table), foreignKey, otherKey

Usage example for relation fields:

export default defineCollection({
  name: 'articles',
  fields: [
    { type: 'string', name: 'title' },
    // Many-to-one: article belongs to one author
    {
      type: 'belongsTo',
      name: 'author',
      target: 'users',
      foreignKey: 'authorId',
    },
    // One-to-many: article has many comments
    {
      type: 'hasMany',
      name: 'comments',
      target: 'comments',
      foreignKey: 'articleId',
    },
    // Many-to-many: article has many tags
    {
      type: 'belongsToMany',
      name: 'tags',
      target: 'tags',
      through: 'articlesTags',  // junction table name
    },
  ],
});

Common Parameters

All column fields support the following parameters:

ParameterTypeDescription
namestringField name (required)
defaultValueanyDefault value
allowNullbooleanWhether null is allowed
uniquebooleanWhether unique
primaryKeybooleanWhether primary key
autoIncrementbooleanWhether auto-increment
indexbooleanWhether to create index
commentstringField comment

Synchronizing Database Structure

When a plugin is first activated, the system will automatically synchronize Collection configurations with the database structure. If the plugin is already installed and running, after adding or modifying Collections, you need to manually execute the upgrade command:

yarn nocobase upgrade

If exceptions or dirty data occur during synchronization, you can rebuild the table structure by reinstalling the application:

yarn nocobase install -f

If you need to migrate existing data during plugin upgrades -- such as renaming fields, splitting tables, backfilling default values, etc. -- you should handle it through Migration scripts rather than manually modifying the database.

Making a Collection Appear in the UI Data Table List

Collections defined via defineCollection are internal server-side tables and by default will not appear in the "Data Source Management" list, nor in the data table selection list when "Adding a Block."

Recommended approach: Add the corresponding data table in the NocoBase "Data Source Management" interface. After configuring the fields and interface types, the table will automatically appear in the block's data table selection list.

Selectable when adding a block

If you really need to register in plugin code (e.g. for demo scenarios in example plugins), you can manually register via addCollection in the client-side plugin. Note that you must register through the eventBus pattern, not directly in load() -- ensureLoaded() will clear and re-set all collections after load(). For a complete example, see Building a Fullstack Data Management Plugin.

Auto-generating Resources

After defining a Collection, NocoBase will automatically generate corresponding REST API resources with out-of-the-box CRUD endpoints (list, get, create, update, destroy) without additional code. If the built-in CRUD operations are not sufficient -- for example, you need a "batch import" or "aggregation statistics" endpoint -- you can register custom actions via resourceManager. See ResourceManager for details.