ResourceManager Manajemen Resource

Fitur manajemen resource NocoBase secara otomatis mengkonversi tabel data (Collection) dan asosiasi (Association) menjadi resource, dan menyediakan beberapa tipe operasi bawaan, sehingga Anda dapat dengan cepat membangun REST API. Sedikit berbeda dengan REST API tradisional, operasi resource NocoBase tidak langsung bergantung pada method HTTP request, tetapi menentukan operasi spesifik yang dieksekusi melalui definisi :action secara eksplisit.

Resource yang Dihasilkan Otomatis

NocoBase secara otomatis akan mengkonversi Collection dan Association yang didefinisikan dalam database menjadi resource. Misalnya mendefinisikan dua collection posts dan tags:

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

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

Sistem akan secara otomatis menghasilkan resource berikut:

  • Resource posts
  • Resource tags
  • Resource asosiasi posts.tags

Contoh request:

Method RequestPathOperasi
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
Method RequestPathOperasi
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
Method RequestPathOperasi
GET/api/posts/1/tags:listQuery semua tags yang terkait dengan post tertentu
GET/api/posts/1/tags:get/1Query single tags di bawah post tertentu
POST/api/posts/1/tags:createMembuat single tags di bawah post tertentu
POST/api/posts/1/tags:update/1Update single tags di bawah post tertentu
POST/api/posts/1/tags:destroy/1Delete single tags di bawah post tertentu
POST/api/posts/1/tags:addMenambahkan tags terkait di bawah post tertentu
POST/api/posts/1/tags:removeMenghapus tags terkait dari post tertentu
POST/api/posts/1/tags:setMengatur semua tags terkait di bawah post tertentu
POST/api/posts/1/tags:toggleToggle asosiasi tags di bawah post tertentu
Tips

Operasi resource NocoBase tidak langsung bergantung pada method HTTP request, tetapi menentukan operasi yang dieksekusi melalui definisi :action secara eksplisit.

Operasi Resource

NocoBase memiliki beberapa tipe operasi bawaan, yang mencakup skenario bisnis umum.

Operasi CRUD Dasar

Nama OperasiPenjelasanTipe Resource yang BerlakuMethod RequestContoh Path
listQuery data listSemuaGET/POST/api/posts:list
getQuery data tunggalSemuaGET/POST/api/posts:get/1
createMembuat record baruSemuaPOST/api/posts:create
updateUpdate recordSemuaPOST/api/posts:update/1
destroyDelete recordSemuaPOST/api/posts:destroy/1
firstOrCreateMencari record pertama, membuat jika tidak adaSemuaPOST/api/users:firstOrCreate
updateOrCreateUpdate record, membuat jika tidak adaSemuaPOST/api/users:updateOrCreate

Operasi Relasi

Nama OperasiPenjelasanTipe Relasi yang BerlakuContoh Path
addMenambahkan asosiasihasMany, belongsToMany/api/posts/1/tags:add
removeMenghapus asosiasihasOne, hasMany, belongsToMany, belongsTo/api/posts/1/comments:remove
setReset asosiasihasOne, hasMany, belongsToMany, belongsTo/api/posts/1/comments:set
toggleMenambah atau menghapus asosiasibelongsToMany/api/posts/1/tags:toggle

Parameter Operasi

Parameter operasi umum termasuk:

  • filter: Kondisi query
  • values: Nilai yang diatur
  • fields: Menentukan field yang dikembalikan
  • appends: Menyertakan data terkait
  • except: Mengecualikan field
  • sort: Aturan sorting
  • page, pageSize: Parameter pagination
  • paginate: Apakah mengaktifkan pagination
  • tree: Apakah mengembalikan struktur tree
  • whitelist, blacklist: Whitelist/blacklist field
  • updateAssociationValues: Apakah memperbarui nilai asosiasi

Operasi Resource Kustom

Anda dapat menggunakan registerActionHandlers untuk mendaftarkan operasi tambahan untuk resource yang ada, mendukung operasi global dan operasi resource khusus.

Mendaftarkan Operasi Global

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

Mendaftarkan Operasi Khusus Resource

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

Contoh request:

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

Aturan penamaan: resourceName:actionName, saat menyertakan asosiasi gunakan sintaks dot (posts.comments).

Resource Kustom

Jika Anda perlu menyediakan resource yang tidak terkait dengan tabel data, dapat menggunakan resourceManager.define untuk mendefinisikan:

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

Method request sama dengan resource otomatis:

  • GET /api/app:getInfo
  • POST /api/app:getInfo (default mendukung GET/POST sekaligus)

Middleware Kustom

Menggunakan resourceManager.use() dapat mendaftarkan middleware global. Misalnya middleware logging global:

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

Property Khusus Context

Dapat memasuki middleware atau action di layer resourceManager, berarti resource tersebut pasti ada. Pada saat ini Anda dapat mengakses konteks request melalui property berikut:

ctx.action

  • ctx.action.actionName: Nama operasi
  • ctx.action.resourceName: Mungkin berupa collection atau association
  • ctx.action.params: Parameter operasi

ctx.dataSource

Objek data source saat ini

ctx.getCurrentRepository()

Objek repository saat ini

Cara Mendapatkan Objek resourceManager dari Data Source yang Berbeda

resourceManager milik data source, Anda dapat mendaftarkan operasi secara terpisah untuk data source yang berbeda.

Data Source Utama

Data source utama dapat langsung menggunakan app.resourceManager:

app.resourceManager.registerActionHandlers();

Data Source Lain

Data source lain dapat memperoleh instance yang sesuai melalui dataSourceManager:

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

Iterasi Semua Data Source

Jika perlu mengeksekusi operasi yang sama untuk semua data source, dapat menggunakan dataSourceManager.afterAddDataSource untuk iterasi:

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

Tautan Terkait