logologo
Get Started
Guide
Development
Plugins
API
English
简体中文
Get Started
Guide
Development
Plugins
API
English
简体中文
logologo

Quick Start

Plugin Development Overview
Write Your First Plugin
Project Structure

Server Development

Overview
Plugin
Collections
Database
DataSourceManager
ResourceManager
ACL
Middleware
Cache
Event
Context
Migration
Logger
I18n
Command
CronJobManager
Test

Client Development

Overview
Plugin
Context
Router
ACL
DataSourceManager
Resource
Request
Styles & Themes
Logger
I18n
Test

Others

Plugin Upgrade Guide
Languages
Dependency Management
Build
Previous PageDataSourceManager
Next PageACL

#ResourceManager

NocoBase's resource management feature can automatically convert existing collections and associations into resources, with built-in operation types to help developers quickly build REST API resource operations. Different from traditional REST APIs, NocoBase resource operations don't rely on HTTP request methods, but determine the specific operation to execute through explicit :action definitions.

#Auto-generating Resources

NocoBase automatically converts collection and association defined in the database into resources. For example, defining two collections, posts and tags:

db.defineCollection({
  name: 'posts',
  fields: [
    { type: 'belongsToMany', name: 'tags' },
  ],
});

db.defineCollection({
  name: 'tags',
  fields: [],
});

This will automatically generate the following resources:

  • posts resource
  • tags resource
  • posts.tags association resource

Request examples:

MethodPathOperation
GET/api/posts:listQuery list
GET/api/posts:get/1Query single
POST/api/posts:createAdd new
POST/api/posts:update/1Update
POST/api/posts:destroy/1Delete
MethodPathOperation
GET/api/tags:listQuery list
GET/api/tags:get/1Query single
POST/api/tags:createAdd new
POST/api/tags:update/1Update
POST/api/tags:destroy/1Delete
MethodPathOperation
GET/api/posts/1/tags:listQuery all tags associated with a post
GET/api/posts/1/tags:get/1Query a single tag under a post
POST/api/posts/1/tags:createCreate a single tag under a post
POST/api/posts/1/tags:update/1Update a single tag under a post
POST/api/posts/1/tags:destroy/1Delete a single tag under a post
POST/api/posts/1/tags:addAdd associated tags to a post
POST/api/posts/1/tags:removeRemove associated tags from a post
POST/api/posts/1/tags:setSet all associated tags for a post
POST/api/posts/1/tags:toggleToggle tags association for a post
Tip

NocoBase resource operations don't directly depend on request methods, but determine operations through explicit :action definitions.

#Resource Operations

NocoBase provides rich built-in operation types to meet various business needs.

#Basic CRUD Operations

Operation NameDescriptionApplicable Resource TypesRequest MethodExample Path
listQuery list dataAllGET/POST/api/posts:list
getQuery single dataAllGET/POST/api/posts:get/1
createCreate new recordAllPOST/api/posts:create
updateUpdate recordAllPOST/api/posts:update/1
destroyDelete recordAllPOST/api/posts:destroy/1
firstOrCreateFind first record, create if not existsAllPOST/api/users:firstOrCreate
updateOrCreateUpdate record, create if not existsAllPOST/api/users:updateOrCreate

#Relationship Operations

Operation NameDescriptionApplicable Relationship TypesExample Path
addAdd associationhasMany, belongsToMany/api/posts/1/tags:add
removeRemove associationhasOne, hasMany, belongsToMany, belongsTo/api/posts/1/comments:remove
setReset associationhasOne, hasMany, belongsToMany, belongsTo/api/posts/1/comments:set
toggleAdd or remove associationbelongsToMany/api/posts/1/tags:toggle

#Operation Parameters

Common operation parameters include:

  • filter: Query conditions
  • values: Values to set
  • fields: Specify returned fields
  • appends: Include associated data
  • except: Exclude fields
  • sort: Sorting rules
  • page, pageSize: Pagination parameters
  • paginate: Whether to enable pagination
  • tree: Whether to return tree structure
  • whitelist, blacklist: Field whitelist/blacklist
  • updateAssociationValues: Whether to update association values

#Custom Resource Operations

NocoBase allows registering additional operations for existing resources. You can use registerActionHandlers to customize operations for all or specific resources.

#Register Global Operations

resourceManager.registerActionHandlers({
  customAction: async (ctx) => {
    ctx.body = { resource: ctx.action.resourceName };
  },
});

#Register Resource-Specific Operations

resourceManager.registerActionHandlers({
  'posts:publish': async (ctx) => publishPost(ctx),
  'posts.comments:pin': async (ctx) => pinComment(ctx),
});

Request examples:

POST /api/posts:customAction
POST /api/posts:publish
POST /api/posts/1/comments:pin

Naming rule: resourceName:actionName, use dot syntax (posts.comments) when including associations.

#Custom Resources

If you need to provide resources unrelated to collections, you can use the resourceManager.define method to define them:

resourceManager.define({
  name: 'app',
  actions: {
    getInfo: async (ctx) => {
      ctx.body = { version: 'v1' };
    },
  },
});

Request methods are consistent with auto-generated resources:

  • GET /api/app:getInfo
  • POST /api/app:getInfo (supports both GET/POST by default)

#Custom Middleware

Use the resourceManager.use() method to register global middleware. For example:

Global logging middleware

resourceManager.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const duration = Date.now() - start;
  console.log(`${ctx.method} ${ctx.path} - ${duration}ms`);
});

#Special Context Properties

Being able to enter the resourceManager layer's middleware or action means the resource must exist.

#ctx.action

  • ctx.action.actionName: Operation name
  • ctx.action.resourceName: Can be a collection or association
  • ctx.action.params: Operation parameters

#ctx.dataSource

The current data source object.

#ctx.getCurrentRepository()

The current repository object.

#How to Get resourceManager Objects for Different Data Sources

resourceManager belongs to a data source, and operations can be registered separately for different data sources.

#Main Data Source

For the main data source, you can directly use app.resourceManager:

app.resourceManager.registerActionHandlers();

#Other Data Sources

For other data sources, you can get a specific data source instance through dataSourceManager and use that instance's resourceManager:

const dataSource = dataSourceManager.get('external');
dataSource.resourceManager.registerActionHandlers();

#Iterate All Data Sources

If you need to perform the same operations on all added data sources, you can use the dataSourceManager.afterAddDataSource method to iterate, ensuring each data source's resourceManager can register the corresponding operations:

dataSourceManager.afterAddDataSource((dataSource) => {
  dataSource.resourceManager.registerActionHandlers();
});