专栏首页Bug生活2048巧用云开发,实现多个小程序访问同一个云数据库

巧用云开发,实现多个小程序访问同一个云数据库

之前的基于ghost的博客小程序,由于服务端快到期了,所以想将数据源切到mini-blog上来。

背景

经常看我文章的知道,我有两个博客小程序(程序员的博客我si程序员)。前者基于开源博客框架ghost。

由于服务器想另做他用,所以打算将程序员的博客的数据源也基于公众号的文章。当然,最简单的方式还是按照mini-blog的部署方式再部署一套。

但再部署一套的缺点就是数据无法打通,文章也就罢了,浏览量,评论数据这些用户行为就相对独立了,这不是我想要的。

于是,利用云开发的HTTP API,来实现跨小程序访问同一个云资源的功能。

云开发 HTTP API

关于云开发 HTTP API的使用,这里就不再多说了,官方的文档写的比较详细了。

之前也有写过一篇利用python操作小程序云数据库实现简单的增删改查,可以参考。

具体改造内容

首先评估下需要改造的点,简单来说原来获取数据源的地方都需要修改,原本是通过本身的云开发API获取本身的数据,而现在相当于是要通过Http请求来通过外网的方式请求数据源。

值得庆幸的是,当初在写mini-blog时,将获取数据源的地方统一收口在api.js中了。这样理论上只需要修改这一个文件的实现,就可以轻松达到目的了。

解决AccessToken问题

一开始觉得挺容易,可刚准备动手就遇到了一个难题,想要使用云开发 HTTP API,首先得获取调用凭证(AccessToken),而要获取调用凭证就需要AppIdSecretId,显然这两个数据比较敏感,放在小程序端是比较危险的。

于是想到,获取AccessToken的动作还是封装在云函数中。但随之而来的另外一个问题就是AccessToken的值存储在哪。

显然没办法放在云资源端(死循环了),于是只能考虑第三方了,我这里使用了bmob后端云

利用小程序云函数,创建一个同步AccessToken的定时任务,每一小时同步一次token值到bmob后端云中,用来供外部访问,核心代码如下:

async function postTokenToBmob(token) {
  var options = {
    method: 'PUT',
    uri: `https://api2.bmob.cn/1/classes/token/X2RgBBBO`,
    body: {
      accessToken: token
    },
    headers: {
      'User-Agent': 'Request-Promise',
      'X-Bmob-Application-Id': BMOBKEY,
      'X-Bmob-REST-API-Key': BMOBPWD
    },
    json: true
  };
  let result = await rp(options)
  console.info(result);
}

重写api.js

解决了token问题,就可以根据官方文档来编写具体实现了,首先编写两个公共方法,一个通过HTTP API调用云数据库,一个通过HTTP API调用云函数,具体代码如下:

/**
 *  查询云数据库
 */
const queryData = async function(query) {
  let token = await getAccessToken()
  var url = `${WECHAT_URL}/tcb/databasequery?access_token=${token}`

  var options = {
    method: 'POST',
    uri: url,
    body: {
      "env": ENV,
      "query": query
    },
    json: true
  };
  return await rp(options)
}

/**
 * 调用云函数
 */
const postAction = async function(data) {
  let token = await getAccessToken()
  let FUNCTION_NAME = "postsService"
  var url = `${WECHAT_URL}/tcb/invokecloudfunction?access_token=${token}&env=${ENV}&name=${FUNCTION_NAME}`
  var options = {
    method: 'POST',
    uri: url,
    body: data,
    json: true
  };
  return await rp(options)
}

然后就可以将原本直接调用云资源的方法重新实现了,拿获取文章列表举例,获取文章列表是通过直接查云数据库实现的,改造后的代码如下:

/**
 * 获取文章列表
 * @param {} page 
 */
const getPostsList = async function(page, filter, isShow, orderBy, label) {
  let where = {}
  let strWhere = ""
  if (filter !== '') {
    strWhere = `title:db.RegExp({regexp:'${filter}',options: 'i',}),`
  }
  if (isShow !== -1) {
    strWhere = strWhere + "isShow:1,"
  }

  if (orderBy == undefined || orderBy == "") {
    orderBy = "createTime"
  }

  if (label != undefined && label != "") {
    strWhere = strWhere + `label:db.RegExp({regexp:'${label}',options: 'i',}),`
  }

  page = (page - 1) * 10

  let query = `db.collection("mini_posts")
  .where({${strWhere}})
  .orderBy("${orderBy}", "desc")
  .skip(${page})
  .limit(10)
  .get()`

  console.info(query)
  let res = await queryData(query)
  return res.data
}

这里有个比较坑的地方是where条件,原本通过对象转成字符串来构造的,但发现构造出来的字符串会有引号,类似{"isShow":1}这样,但实际调用接口会提示语法错误,后来发现在构造查询语句时要的是类似{isShow:1}这样,不带引号的。

但奇葩的是,排序的变量又是需要引号的,类似.orderBy("createTime", "desc")这样。真的要被腾讯玩坏了。

而调用云函数就比较简单了,传个云函数名称和对应的参数就行了,就不贴代码了。

重写api.js之后的坑

原本以为大功告成了,结果是我想多了。

不得不吐槽下云开发的返回体的定义,没有一个标准,云数据库、云函数、HTTP API的返回体都不一样(可能不是一波人写的,但好歹一个大团队,不能规范下嘛)

于是在成功获取完数据之后,为了不动到页面的代码,将返回结果再构造成之前的样子:

function buildDataResult(res) {
    let result = {}
    let jsonData = []
    if (res != null) {
        for (let i = 0, len = res.result.length; i < len; i++) {
            jsonData.push(JSON.parse(res.result[i]))
        }
    }
    result.data = jsonData
    return result
}

到这里,大多数页面都已经可以正常展示了,还差几个功能按钮了。

评论、收藏、点赞的按钮,这里有点小坑,openId的问题,原先是直接在云函数端获取用户的openId去保存的。

但通过Http访问云资源端就需要自己传了,需要重写下原来的云函数,优先取传入的openId。

openId: event.openId == undefined ? event.userInfo.openId : event.openId

总结

绕了一圈把功能实现了,也算对小程序、云开发又有了新的认识吧。

同时,代码一些细节挺重要的,可能会直接影响到后续迭代的工作量。比如调用数据的方法收口,如果当初是散落在各个页面的,那这改造的工作量就大了很多。

最后,保持统一的输入输出规范也很重要,统一的标准不管是提供方还是接入方,都会事半功倍。

有了这个经验和实现,下一步就要把数据搬到QQ小程序上了,这个改造应该也不大,后面实现了再分享给大家。

本文分享自微信公众号 - Bug生活2048(BugLife2048),作者:Bug2048

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • QCon全球软件开发大会随笔(二)

    对于大会的介绍这里就省略了,上一篇随笔基本都提到了,这里主要记录下我听的几场专题的一些收获和自己的一些想法。

    Bug生活2048
  • 分享几个关于微信小程序的开源项目

    腾讯团队官方的教程demo,对于云开发不太了解的可以在熟悉云开发文档之后学习下demo代码

    Bug生活2048
  • Python实战-解决工作中的重复工作(一)

    目前公司的项目管理采用开源项目redmine,对于redmine本文不多做介绍,有兴趣的可以自行百度了解下。

    Bug生活2048
  • 前端-6个减少JavaScript错误噪音的技巧

    通过Web开发人员提供的这六个重要提示,了解如何减少JavaScript错误噪音并找到JavaScript zen。请继续阅读!

    grain先森
  • 可声控的VR惊悚游戏《Stifled》,“听见”你的恐惧!

    在荒郊野外翻车的主人公David Ridley,无计可施之下只能摸黑前進。一路上散落的血跡、鞋子,以及神祕的厂房,都让人感到毛骨悚然,这里究竟隐藏着什么秘密?

    VRPinea
  • 【报告】人工智能时代,10 年之后我们还能干什么?

    摘要:10年之后我们还能做什么? 根据耶鲁大学和牛津大学的研究人员对 352 位人工智能专家进行了采访,人工智能到2060 年前后有 50%的概率完全超过人类。...

    钱塘数据
  • SAP S/4HANA最佳业务实践:Order-to-Cash订单到收款-4报价单处理

    •The tile Manage Sales Quotationsis part of the business catalog Sales –Quotatio...

    SAP最佳业务实践
  • MCMC(四)Gibbs采样

        在MCMC(三)MCMC采样和M-H采样中,我们讲到了M-H采样已经可以很好的解决蒙特卡罗方法需要的任意概率分布的样本集的问题。但是M-H采样有两个缺点...

    刘建平Pinard
  • AI风向标:发改委重大工程项目公布,首个无人车路测试点落户亦庄

    李根 发自 凹非寺 量子位 报道 | 公众号 QbitAI 还记得教科书里的“经济基础决定上层建筑”、“生产关系反作用于生产力”吗? 2018年刚开始,过往以...

    量子位
  • Flask web 开发出现错误:Typ

    没有发现普通都语法错误,然后一一比对官方教程里面的代码,发现是在“@bp.route('/<int:id>/delete', methods=('POST'))...

    py3study

扫码关注云+社区

领取腾讯云代金券