ResourceManager

NocoBase's resource management automatically converts Collections and Associations into resources, with built-in operation types that allow you to quickly build REST APIs. Unlike traditional REST APIs, NocoBase resource operations don't directly depend on HTTP request methods, but determine the specific operation to execute through explicit :action definitions.

Auto-generating Resources

NocoBase automatically converts Collections and Associations 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:createCreate
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:createCreate
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 HTTP request methods, but determine operations through explicit :action definitions.

Resource Operations

NocoBase provides built-in operation types covering common business scenarios.

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

You can use registerActionHandlers to register additional operations for existing resources, supporting both global and resource-specific operations.

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 data tables, you can use resourceManager.define 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 resourceManager.use() to register global middleware. For example, a 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. You can access the request context through the following properties:

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 you can register operations 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 the corresponding instance through dataSourceManager:

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

Iterate All Data Sources

If you need to perform the same operations on all data sources, you can use dataSourceManager.afterAddDataSource to iterate:

dataSourceManager.afterAddDataSource((dataSource) => {
  dataSource.resourceManager.registerActionHandlers();
});
  • Resource API Reference — Full method signatures and usage for client-side MultiRecordResource / SingleRecordResource
  • ACL — Configure role permissions and access control for resource operations
  • Context — Access context information in request handlers
  • Middleware — Add interception and processing logic for requests
  • DataSourceManager — Manage multiple data sources and their resource managers
  • Collections — Automatic mapping between Collections and Resources