前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >巧用云开发,实现多个小程序访问同一个云数据库

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

作者头像
Bug生活2048
发布2019-09-09 17:35:46
4.4K0
发布2019-09-09 17:35:46
举报
文章被收录于专栏:Bug生活2048Bug生活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后端云中,用来供外部访问,核心代码如下:

代码语言:javascript
复制
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调用云函数,具体代码如下:

代码语言:javascript
复制
/**
 *  查询云数据库
 */
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)
}

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

代码语言:javascript
复制
/**
 * 获取文章列表
 * @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的返回体都不一样(可能不是一波人写的,但好歹一个大团队,不能规范下嘛)

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

代码语言:javascript
复制
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。

代码语言:javascript
复制
openId: event.openId == undefined ? event.userInfo.openId : event.openId

总结

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

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

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Bug生活2048 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云函数
云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档