原子指令

2018-11-28 07:31:34

Cabloy将所有业务数据的操作称为原子指令,主要分两类:

  1. 基本指令create、read、write、delete
  2. 扩展指令:与具体业务相关的操作,如review、publish等等

Cabloy提供了一套基础API路由,对原子指令进行了封装,这样可以统一配置数据库事务、验证器、数据权限等中间件

业务模块只需提供扩展逻辑路由即可,这些扩展逻辑路由会在合适的时候被基础API路由调用

基本指令

常量定义

模块a-base提供了基本指令的通用逻辑,其常量定义如下:

a-base/backend/src/config/constants.js

atom: {
  action: {
    create: 1,
    read: 2,
    write: 3,
    delete: 4,
    save: 51,
    submit: 52,
    custom: 100, // custom action start from custom
  },
  actionMeta: {
    create: { title: 'Create', actionComponent: 'action' },
    read: { title: 'View', actionPath: 'atom/view?atomId={{atomId}}&itemId={{itemId}}&atomClassId={{atomClassId}}&module={{module}}&atomClassName={{atomClassName}}&atomClassIdParent={{atomClassIdParent}}' },
    write: { title: 'Edit', actionPath: 'atom/edit?atomId={{atomId}}&itemId={{itemId}}&atomClassId={{atomClassId}}&module={{module}}&atomClassName={{atomClassName}}&atomClassIdParent={{atomClassIdParent}}' },
    delete: { title: 'Delete', actionComponent: 'action' },
    save: { title: 'Save', actionComponent: 'action', authorize: false },
    submit: { title: 'Submit', actionComponent: 'action', authorize: false },
    custom: { title: 'Custom' },
  },
},
名称 说明
title 指令的标题
actionModule 前端处理组件所属模块名,默认为当前所属模块
actionComponent 前端处理组件名
actionPath 前端页面组件路径
authorize 是否需要单独授权。因为savesubmitwrite的辅助指令,所以不需要单独授权
custom 指令占位符,扩展指令从101开始

模块a-base提供的基本指令通用逻辑可满足大多数场景需求,如果想定制基本指令的逻辑,只需像扩展指令一样,提供自定义的actionModuleactionComponentactionPath组合即可

基本API路由

模块a-base提供的后端路由,封装了事务验证器权限等中间件的配置,如下:

a-base/backend/src/routes.js

{ method: 'post', path: 'atom/create', controller: atom, middlewares: 'transaction',
  meta: { right: { type: 'atom', action: 1 } },
},
{ method: 'post', path: 'atom/read', controller: atom,
  meta: { right: { type: 'atom', action: 2 } },
},
{ method: 'post', path: 'atom/select', controller: atom },
{ method: 'post', path: 'atom/write', controller: atom, middlewares: 'validate,transaction',
  meta: {
    right: { type: 'atom', action: 3 },
    validate: { data: 'item' },
  },
},
{ method: 'post', path: 'atom/submit', controller: atom, middlewares: 'validate,transaction',
  meta: {
    right: { type: 'atom', action: 3 },
    validate: { data: 'item' },
  },
},
{ method: 'post', path: 'atom/delete', controller: atom, middlewares: 'transaction',
  meta: { right: { type: 'atom', action: 4 } },
},

扩展API路由

业务模块只需提供扩展逻辑路由,即可在基本逻辑的基础上做一些扩展操作。如模块test-todo的路由配置如下:

modules/test-todo/backend/src/routes.js

{ method: 'post', path: 'todo/create', controller: todo, middlewares: 'inner' },
{ method: 'post', path: 'todo/read', controller: todo, middlewares: 'inner' },
{ method: 'post', path: 'todo/select', controller: todo, middlewares: 'inner' },
{ method: 'post', path: 'todo/write', controller: todo, middlewares: 'inner' },
{ method: 'post', path: 'todo/delete', controller: todo, middlewares: 'inner' },

扩展逻辑

src/module/test-todo/backend/src/service/todo.js

create

create扩展逻辑一般执行以下操作:

  1. 新建业务表条目
  2. 初始化atom字段值(可选)
  3. 返回atom key
async create({ atomClass, key, item, user }) {
  // add todo
  const res = await this.ctx.model.todo.insert({
    atomId: key.atomId,
  });
  // return key
  return { atomId: key.atomId, itemId: res.insertId };
}

read

read扩展逻辑一般为空,因为这时对象item已经提取了原子的基本表业务表的数据

如果想附加基本表业务表之外的数据,可在这里直接操作对象item

async read({ atomClass, key, item, user }) {
  // read
  item.otherField = 'other';
}

select

select扩展逻辑一般为空,因为这时对象items已经提取了原子的基本表业务表的数据

如果想附加基本表业务表之外的数据,可在这里直接操作对象items

async select({ atomClass, options, items, user }) {
  // select
  for (const item of items) {
    item.otherField = 'other';
  }
}

write

write扩展逻辑一般执行以下操作:

  1. 修改业务表条目
async write({ atomClass, key, item, validation, user }) {
  // update todo
  await this.ctx.model.todo.update({
    id: key.itemId,
    description: item.description,
  });
}

delete

delete扩展逻辑一般执行以下操作:

  1. 删除业务表条目
async delete({ atomClass, key, user }) {
  // delete todo
  await this.ctx.model.todo.delete({
    id: key.itemId,
  });
}

扩展指令

可以通过扩展指令实现与具体业务相关的操作

扩展指令定义

如为原子类型todo增加review操作,扩展指令配置如下:

src/module/test-todo/backend/src/meta.js

const meta = {
  base: {
    atoms: {
      todo: {
        actions: {
          review: {
            code: 101,
            title: 'Review',
            flag: '1',
          },
        },
        flags: {
          1: {
            title: 'Reviewing',
          },
          2: {
            title: 'Reviewed',
          },
        },
      },
    },
  },
};
名称 说明
review.code 扩展指令代码
review.title 扩展指令标题
review.flag 原子标记
flags 原子标记定义

基本API路由

核心模块a-base实现了对扩展指令的统一分发,其提供的后端路由封装了事务验证器权限等中间件的配置,如下:

a-base/backend/src/routes.js

{ method: 'post', path: 'atom/action', controller: atom, middlewares: 'validate,transaction',
  meta: {
    right: { type: 'atom' },
    validate: { data: 'item' },
  },
},

扩展API路由

业务模块只需提供扩展逻辑路由,以便对相应的指令进行逻辑处理。如模块test-todo的路由配置如下:

src/module/test-todo/backend/src/routes.js

{ method: 'post', path: 'todo/action', controller: todo, middlewares: 'inner' },

扩展逻辑

src/module/test-todo/backend/src/service/todo.js

action

action需针对不同的指令代码进行相应的逻辑处理:

async action({ action, atomClass, key, user }) {
  if (action === 101) {
    // do something
  }
}


评论: