社区/学习指南/小程序·云开发高级教程

云函数路由tcb-router

tcb-router 是基于 Nodejs koa 风格的云开发云函数轻量级的类路由库,可以用于优化前端(小程序端)调用服务端的云函数时的处理逻辑。我们可以使用它在一个云函数里集成多个类似功能的云函数,比如针对某个集合的增删改查;也可以把后端的一些零散功能集成到一个云函数里,便于集中管理等。

11.11.1 tcb-router 快速入门

tcb-router 主要用于小程序端调用云函数时的处理逻辑,在小程序端使用 wx.cloud.callFunction 调用云函数时,我们需要在 name 里传入要调用的云函数名称,以及在 data 里传入要调用的路由的路径;而在云函数端使用 app.router 来写对应的路由的处理函数。

使用开发者工具,创建一个云函数,如 router,然后在 package.json 增加 tcb-router 最新版 latest 的依赖并用 npm install 安装:


"dependencies": {

  "wx-server-sdk":"latest",

  "tcb-router": "latest"

}

然后在 index.js 里输入以下代码,其中app.use表示该中间件适用于所有的路由,而app.router('user')则适用于路由为字符串'user'的中间件,ctx.body为返回给小程序端的数据,返回的方式是通过return app.serve():

const cloud = require("wx-server-sdk");

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
});

const TcbRouter = require("tcb-router");

exports.main = async (event, context) => {
  const app = new TcbRouter({ event });

  const { OPENID } = cloud.getWXContext();

  app.use(async (ctx, next) => {
    //适用于所有的路由

    ctx.data = {}; //声明data为一个对象

    await next();
  });

  app.router("user", async (ctx, next) => {
    //路由为user

    ctx.data.openId = OPENID;

    ctx.data.name = "李东bbsky";

    ctx.data.interest = ["爬山", "旅游", "读书"];

    ctx.body = {
      //返回到小程序端的数据

      openid: ctx.data.openId,

      姓名: ctx.data.name,

      兴趣: ctx.data.interest,
    };
  });

  return app.serve();
};

而在小程序端,我们可以用事件处理函数或者生命周期函数来调用创建好的 router 云函数,就能在 res 对象里获取到云函数 router 返回的 ctx.body 里的对象了:

wx.cloud
  .callFunction({
    name: "router",

    data: {
      $url: "user", //路由为字符串user,注意属性为 $url
    },
  })
  .then((res) => {
    console.log(res);
  });

11.11.2 tcb-router 管理数据库的增删改查

使用 tcb-router 还可以管理数据库的集合,我们可以把一个集合(也可以是多个集合)的 add、remove、update、get 等集成到一个云函数里,可以看下面具体的案例,我们在 router 云函数里输入以下代码:

const cloud = require("wx-server-sdk");

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV,
});

const TcbRouter = require("tcb-router");

const db = cloud.database();

const _ = db.command;

const $ = db.command.aggregate;

exports.main = async (event, context) => {
  const collection = ""; //数据库的名称

  const app = new TcbRouter({ event });

  const {
    adddata,
    deleteid,
    updatedata,
    querydata,
    updateid,
    updatequery,
  } = event;

  app.use(async (ctx, next) => {
    ctx.data = {};

    await next();
  });

  app.router("add", async (ctx, next) => {
    const addresult = await db.collection(collection).add({
      data: adddata,
    });

    ctx.data.addresult = addresult;

    ctx.body = { 添加记录的返回结果: ctx.data.addresult };
  });

  app.router("delete", async (ctx, next) => {
    const deleteresult = await db
      .collection(collection)
      .where({
        id: deleteid,
      })
      .remove();

    ctx.data.deleteresult = deleteresult;

    ctx.body = { 删除记录的返回结果: ctx.data.deleteresult };
  });

  app.router("update", async (ctx, next) => {
    const getdata = await db
      .collection(collection)
      .where({
        id: updateid,
      })
      .update({
        data: updatedata,
      });

    ctx.data.getresult = getdata;

    ctx.body = { 查询记录的返回结果: ctx.data.getresult };
  });

  app.router("get", async (ctx, next) => {
    const getdata = await db.collection(collection).where(querydata).get();

    ctx.data.getresult = getdata;

    ctx.body = { 查询记录的返回结果: ctx.data.getresult };
  });

  return app.serve();
};

然后再在小程序端相应的事件处理函数里使用 wx.cloud.callFunction 传入相应的云函数以及相应的路由$url以及传入对应的 data 值即可:

//新增一条记录

wx.cloud
  .callFunction({
    name: "router", //router云函数

    data: {
      $url: "add",

      adddata: {
        id: "202006031020",

        title: "云数据库的最佳实践",

        content: "<p>文章的富文本内容</p>",

        createTime: Date.now(),
      },
    },
  })
  .then((res) => {
    console.log(res);
  });

//删除一条记录

wx.cloud
  .callFunction({
    name: "router",

    data: {
      $url: "delete",

      deleteid: "202006031020",
    },
  })
  .then((res) => {
    console.log(res);
  });

//查询记录

wx.cloud
  .callFunction({
    name: "router",

    data: {
      $url: "get",

      querydata: {
        id: "202006031020",
      },
    },
  })
  .then((res) => {
    console.log(res);
  });

关于 tcb-router 更多进阶用法,可以查看技术文档:tcb-router Github 地址。使用 tcb-router 时的一些说明:

  • 通常情况下,我们不建议大家使用一个云函数来调用其他云函数这种做法,这种做法会导致云函数的执行时间会增加很多,而且还会耗费云函数的资源,我们可以使用 tcb-router 来处理需要跨云函数调用的情况;

  • 值得注意的是,tcb-router 会把所有云函数的承载放在一个云函数里,对并发有比较高要求的云函数建议不要把用 tcb-router 整到一个里面。每个云函数的并发数上限为 1000,这本可以每秒处理十万级别的请求,但是如果把大量不同的云函数都集成到一个里面,尤其是一些耗时比较长的云函数会严重拖性能后退,而这些云函数都会共享这 1000 个并发,所以要注意根据情况来抉择了;

  • 云函数会有一个冷启动时间(比如十分钟以上没人调用这个云函数,当再首次调用这个云函数会比较慢),当我们把多个功能相似、并发不会特别高(低于每秒几千)的云函数使用 tcb-router 集成到一个云函数里,这样就可以减少冷启动的可能性了;

本文出自 李东bbsky