知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
小程序云函數(shù)接口設(shè)計
發(fā)表時間:2021-1-5
發(fā)布人:葵宇科技
瀏覽次數(shù):73
微信為小程序開發(fā)者提供了云函數(shù),作為替代后臺的一種serverless解決方案。微信云函數(shù)與微信小程序前端功能結(jié)合的很緊密,為開發(fā)者提供了相當(dāng)大的便利。但云函數(shù)在設(shè)計、開發(fā)、調(diào)試上與傳統(tǒng)的服務(wù)端開發(fā)有著許多不同。
我們的團(tuán)隊近期開發(fā)了一款小程序產(chǎn)品。為了更大程度的減少server的使用,業(yè)務(wù)后臺完全使用云函數(shù)提供服務(wù)(主要是我們的團(tuán)隊沒有專業(yè)后端-_-)。另外采用前端童鞋熟悉的eggjs+vue做了一套簡易的管理后臺,用來進(jìn)行審核和數(shù)據(jù)管理工作。
系統(tǒng)分為小程序端,云函數(shù)端,web端。數(shù)據(jù)庫使用云服務(wù)的數(shù)據(jù)庫。
一、云函數(shù)調(diào)用通用接口定義
1、云端
我們在云端封裝了一個通用的runFunc方法,所有的云函數(shù)都走這個方法然后再根據(jù)fname
分別進(jìn)入對應(yīng)函數(shù)處理。
runFunc基本的入?yún)ⅲ?/p>
屬性 | 含義 |
---|---|
fname | 自定義云函數(shù)名 |
clientType | 小程序端/web端 |
version | 版本信息,用于必要時進(jìn)行更新干預(yù)控制 |
token | 用戶token |
adminOpenId | web端用戶的openid不能自動獲取,需要手動傳入 |
runFunc基本的處理流程,會順序進(jìn)行一系列判斷:
代碼:
//cloudfunctions/runFunc/index.js
async function main(event, context) {
let {fname, version, token, clientType, adminOpenId, ...opt} = event
let result, role
const { OPENID } = cloud.getWXContext()
//先校驗fname是否存在
if(!fname){
return {code: '0422', info:'參數(shù)錯誤'}
}
//getToken方法
if(fname==='getToken'){
return await getToken(cloud, db)
}
//小程序端,需要校驗版本
if(clientType===0){
if (semver.lt(version, LOWEST_VERSION)) {
return {code: '0602', info: '當(dāng)前版本過低!'}
}
const authResult = authCheck(token)
role = authResult.role
//校驗token
if(!token || authResult.unauthorized) {
return {code: '0401', info: '用戶狀態(tài)失效', data: {role}}
}
} else {
role = opt.role
}
switch(fname){
case 'getList':
return await getList()
//...
default:
return {code: '0404', info:'未找到對應(yīng)方法'}
}
}
復(fù)制代碼
2、小程序端
在小程序端,我們也對應(yīng)封裝一個云函數(shù)調(diào)用方法,可以集中處理標(biāo)準(zhǔn)的云函數(shù)調(diào)用錯誤。
遺憾的是,官方文檔沒有給出標(biāo)準(zhǔn)的云函數(shù)返回值定義,通過調(diào)試,發(fā)現(xiàn)云函數(shù)調(diào)用通常會拋出errCode, errMsg, requestId, result
這些值,通常errCode為空時執(zhí)行正常,但有些方法執(zhí)行失敗也不返回errCode(什么鬼……)在官方論壇上提問也沒有得到回復(fù),我們只能通過errCode || !/ok/.test(errMsg)
來判斷是不是執(zhí)行失敗了。
//miniprogram/utils/api.js/callCloud
const app = getApp()
async function callCloud(fname, opt){
try{
const {errCode, errMsg, requestId, result} = await wx.cloud.callFunction({
name: 'runFunc',
data: {
fname,
clientType: 0,
version: app.globalData.appVersion,
token: app.globalData.token,
...opt
}
})
if(errCode || !/ok/.test(errMsg)){
wx.showToast({
title: '服務(wù)器錯誤',
icon: 'none',
duration: 2000
})
return {code: '0700', info: '服務(wù)器繁忙', subcode: errCode, subinfo: errMsg}
}
else {
const {code, info, data} = result
if(code === '0401'){
wx.showToast({
title: info,
duration: 2000
})
}
if(code === '0602'){
// todo: 做強(qiáng)制升級代碼
wx.showToast({
title: info || '去強(qiáng)制升級',
icon: 'none',
duration: 2000
})
}
if(code!=='0000'){
wx.showToast({
title: info || '錯誤',
icon: 'none',
duration: 2000
})
}
return result
}
} catch(e){
return {code: '0500', info: e.message || '服務(wù)器繁忙'}
}
}
exports.callCloud = callCloud
復(fù)制代碼
在page的js里,調(diào)用云函數(shù):
//miniprogram/pages/demo/demo.js
const api = require('../../utils/api')
Page({
data:{///...},
onLoad: async function(){
const {code, info} = await api.callCloud('getList')
//...
}
})
復(fù)制代碼
3、web端-接口
在web服務(wù)端,我們提供一個通用的調(diào)用云函數(shù)的route
//router.js
router.post('/call/:funcname', jwt, controller.home.callCloudFunction)
復(fù)制代碼
在controller里我們發(fā)送如下的url請求:
POST https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=ACCESS_TOKEN&env=ENV&name=FUNCTION_NAME
復(fù)制代碼
//home.controller
const url = util.format('https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=%s&env=%s&name=%s', access_token, cloudEnv, functionName)
const { data: optData, ...restOpt } = opt
const result = await ctx.curl(url, {
method: 'POST',
contentType: 'json',
dataType: 'json',
data: {
clientType: 1,
adminOpenId: ctx.state.user && ctx.state.user.openId ? ctx.state.user.openId : '',
role: ctx.state.user && ctx.state.user.role ? parseInt(ctx.state.user.role) : 0,
...optData
},
...restOpt
})
const { errcode, errmsg, resp_data } = result.data
/*
errcode為空,返回JSON.parse(resp_data)
errcode不為空,返回對應(yīng)的errmsg
*/
復(fù)制代碼
4、web端-前端
對應(yīng)的,web前端的調(diào)用非常簡單:
const {code, info, data} = await axios('/call/runFunc', { data: {fname: functionName, options} })
復(fù)制代碼
這樣我們保證云函數(shù)的數(shù)據(jù)結(jié)構(gòu),錯誤碼在三端都是統(tǒng)一的。
二、關(guān)于用戶狀態(tài)
常規(guī)web項目或者app項目,都是用token來做用戶登錄狀態(tài)保持。
在小程序里使用云函數(shù)的好處之一是無需自己寫登錄流程,小程序端的每個請求均可通過云端的cloud.getWXContext()
方法均輕松獲得用戶的openid,如下:
const { OPENID } = cloud.getWXContext()
復(fù)制代碼
那么在小程序項目是否只需要openid,不再需要token了呢?我依然建議通過token來標(biāo)識用戶的有效性,因為在token中可以攜帶用戶角色\登錄時間等信息,用于更精細(xì)的業(yè)務(wù)控制。
//云函數(shù)端
const token = encode({ t: now, r: role })
復(fù)制代碼
用戶進(jìn)入首頁后如果token不存在或失效,通過調(diào)用云端getToken方法進(jìn)行更新token,同時在user表中新增或更新該用戶的記錄。
//小程序端,如果沒有token,去取token
if(!app.globalData.token){
app.globalData.token = await api.callCloud('getToken')
}
復(fù)制代碼
api.callCloud就是前面所述的自定義云函數(shù)的通用方法。
//云端的getToken方法
async function getToken(cloud, db){
try{
const { OPENID } = cloud.getWXContext()
let result = await db.collection('user').where({openId: OPENID}).get()
//如果用戶表中已經(jīng)存在這個用戶,更新用戶的最近登錄時間
if(result.data && result.data.length>0){
await db.collection('user').where({openId: OPENID}).update({
data: {
latestTime: now
}
})
token = encode({ d: now, r: record.role })
return {code: '0000', info: '成功', data: {token, openId: OPENID, role: record.role}}
}
} else{
let record = {
openId: OPENID,
firstTime: now,
latestTime: now,
role: 0
}
//如果user標(biāo)準(zhǔn)沒有這個用戶,則新增一條用戶記錄
await db.collection('user').add({
data: record
})
token = encode({ d: now, r:0})
return {code: '0000', info: '成功', data: {token, openId: OPENID, role: 0}}
}
}catch(e){
return {code: '0500', info: e.message || '系統(tǒng)錯誤'}
}
}
復(fù)制代碼
web端可以通過小程序端掃碼進(jìn)行登錄,這樣就可以在web端也帶入用戶的openid,與小程序端使用同一套用戶體系。
作者:dunhuang
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
相關(guān)案例查看更多
相關(guān)閱讀
- 昆明小程序哪家好
- 文山小程序開發(fā)
- 安家微信小程序
- 云南旅游網(wǎng)站建設(shè)
- 昆明做網(wǎng)站建設(shè)的公司排名
- 云南小程序開發(fā)哪家好
- 昆明軟件定制公司
- 網(wǎng)站建設(shè)案例
- uniapp開發(fā)小程序
- 網(wǎng)絡(luò)公司排名
- 微信小程序開發(fā)入門課程
- 云南網(wǎng)站優(yōu)化公司
- 汽車回收管理系統(tǒng)
- 小程序分銷商城
- 小程序被攻擊
- 網(wǎng)站建設(shè)靠譜公司
- 汽車報廢回收管理系統(tǒng)
- 小程序生成海報
- 海報插件
- 云南網(wǎng)站建設(shè)開發(fā)
- 云南省城鄉(xiāng)建設(shè)廳網(wǎng)站
- 河南小程序制作
- 云南網(wǎng)站建設(shè)靠譜公司
- 云南網(wǎng)站建設(shè)招商
- 買小程序被騙
- 專業(yè)網(wǎng)站建設(shè)公司
- 云南網(wǎng)站建設(shè)公司
- 汽車報廢回收
- 排名
- 大理網(wǎng)站建設(shè)公司