個人介紹
大家好,我是Zero,一名大四的前端開發愛好者,目前主要研究微信小程序和iOS開發。
這是第二次參加微信小程序應用開發賽,2018年我們設計了一款通過二維碼尋找丟失物品的小程序《蝴蝶尋物》,獲得了華北賽區三等獎。
今年,在小程序雲開發功能的大力推廣下,我決定採用雲開發的方式,實現一個雙人互動打卡互動的小程序《Mango Daily》(中文名稱《芒果日常》)。(由於是個人開發者賬號,所以暫時還未上架)
得力於雲開發提供的API,本項目在較短的時間內就實現了比較理想的效果。
接下來,我想從本項目入手,講講我是如何依靠小程序+雲開發平臺將想法快速實現的。
1. 技術準備
在去年的項目中,我們採用ThinkPHP開發了一套API系統,其中需要實現小程序的授權登錄,設置鑑權來保證數據安全等操作。整個過程只有我一名開發人員,所以大致就是“先搞定後端,其次搞定界面,最後進行聯調”的一個過程。
後來在雲+社區看到一篇文章:《1個開發如何撐起一個過億用戶的小程序》,覺得可以嘗試一下新的開發方式。通讀小程序雲開發文檔之後,發現並不需要學習新的技術就可以快速上手。
2. 開發
Mango Daily 使用的是小程序原生開發+雲開發結合的方式進行開發的。
2.1 界面開發
界面沒有使用第三方UI框架,而是自己將常用的模塊封裝成了組件。
圖中比較核心的模塊包括 TabBar、Toast、Modal、Nav等。
2.2 雲開發
雲開發包括雲數據庫,雲函數和雲存儲。本項目中三個功能均使用到。
2.2.1 雲數據庫
雲數據庫是一個非關係型數據庫,在實際開發中基本符合本項目的需求。部分表關聯查詢則是通過分步查詢的方式代替。
雲數據庫已經實現了自動鑑權,可以保證數據的安全性。目前雲數據庫只支持以下幾種權限:
- 所有用戶可讀,僅創建者可讀寫
- 僅創建者可讀寫
- 所有用戶可讀
- 所有用戶不可讀寫
默認情況下是僅創建者可讀寫,所以在首次開發時,手動插入的測試數據並不一定可以在前端順利讀取,需要修改集合的權限。
雲數據庫的調用在前端代碼中即可完成。但是從上面幾種讀寫權限來看,並沒有辦法實現對另一個用戶創建的數據進行修改或者刪除的操作(當然這也是非常不可取的),於是雲函數就派上用場了。
2.2.2 雲函數
我理解的雲函數,則是跑在雲端的一個函數腳本文件。
在接觸雲開發之前,如果我們想要去調用微信公衆平臺提供的API(例如發起退款、發送模板消息等),則需要在後端代碼去實現,然後只需要給前端返回一個JSON表示請求狀態即可。或者想要去實現上述描述中,修改一條由他人創建的數據的功能時,都是有後端工程師去完成的。
在本次開發中,我深刻體會到了雲函數的強大,以及微信公衆平臺工程師設計產品的嚴謹性。
Mango Daily用到了微信公衆平臺的模板消息功能,所以需要在合適的時機請求微信官方提供的API。
因爲取消了後端的開發,所以一開始打算直接在小程序端去請求官方API。但是失敗了。因爲此請求涉及APPKEY等重要信息,禁止在小程序端代碼中直接請求官方API。這樣就可以通過雲函數去代替先前的後端開發,最後將狀態返回給小程序端即可。
例如想給新用戶發送一條短信,以往的做法是客戶端請求後端API,然後由後端完成發送短信操作。這裏雲函數就代替了後端開發。如果僅僅依靠小程序JS代碼去發送短信,是非常不可取的。
另外,雲函數對雲數據庫有更高的操作權限,所以想要修改、刪除他人生成的數據時,雲函數可以直接進行操作。
雲函數還提供定時觸發功能,不過在本項目中暫未涉及。
2.2.3 雲存儲
本次開發省去了使用其他服務商的存儲服務,全部得力於雲存儲功能。雲存儲允許上傳多種文件類型,像圖片、音頻等文件還可以直接在小程序端調用。這裏我們使用雲存儲實現了文章插圖的功能。
2.3 優化
2.3.1 數據層封裝
Mango Daily 數據操作進行了兩次封裝,一層是對雲數據庫API進行封裝,第二層是每一個數據集合都對應一個Manager管理層。
以用戶集合 User,Article 爲例,項目中的結構如下:
util
|- db.js
manager
|- Article.js
|- User.js
db.js 是對雲數據庫API的封裝,實現了增刪查改等操作,以更新數據爲例。
/**
* 更新數據
*/
const update = (collection, _id, data) => {
return new Promise((resolve, reject) => {
if (!exist(collection)) {
reject(401, resCode[401]);
}
db.collection(collection).doc(_id).update({
data: data
}).then(res => {
resolve(res);
}).catch((code, msg) => {
reject(code, msg);
});
});
}
Article.js 是文章集合的管理類,同樣實現了增刪查改等操作,不過其是基於 db.js 進行擴展的。以更新文章操作爲例:
/**
* 更新
*/
const update = (_id, data) => {
return new Promise((resolve, reject) => {
db.update(collection, _id, data).then(res => {
resolve(res);
}).catch((code, msg) => {
reject(db.errMsg);
});
});
}
之所以封裝兩層,是想盡量減少Page對象中對雲數據庫的直接調用。這樣在頁面js文件中只需要調用某一個Manager提供的函數即可。
2.3.3 後臺上傳策略
Mango Daily還實現了發送模板消息的功能,這就涉及到了FromID的收集。目前FromID的收集大部分採用埋點的方式。
如果每次採集到新的FromID都直接上傳到數據庫存儲,可能會造成網絡資源的浪費,所以需要選擇合適的時機上傳數據。
在本項目中,每次採集到FromID,首先存到 globalData 中,當小程序進入後臺狀態時,再進行數據的上傳。
app.js 中的實現:
/**
* 後臺監聽
*/
onHide: function() {
this.uploadFormID();
},
/**
* 上傳token
*/
uploadFormID: function() {
let ids = this.globalData.formIds;
if (ids.length == 0) {
return ;
}
let formId = ids.pop();
this.push.upload(formId).then(_ => {
console.log("上傳formID:" , formId);
this.uploadFormID();
}).catch(err => {
console.log(err);
});
},
3. 維護
很遺憾,這一部分可能沒有太多需要寫的。
在18年的項目中,需要考慮數據庫的維護問題。但是使用了雲開發之後,Serverless的優點就表現出來了。我無須將太多的精力放在後端的維護上。
4. 總結
在本次項目開發中,我深刻體會到了雲開發的便捷性。無須自己實現鑑權,對接第三方存儲。數據方面,增刪查改功能非常方便。雲開發提供的種種便利,讓我在有新創意的時候,優先選擇小程序+雲開發的方式去實現。
另外,Mango Daily中的隨筆功能屬於用戶自行生成內容功能,所以在上架的時候,個人開發者賬號是不被允許的,所以在考慮上架產品的時候,請按照實際情況酌情考慮選擇賬號主體類型。
源碼地址
https://github.com/TencentCloudBase/Good-practice-tutorial-recommended
如果你想要了解更多關於雲開發CloudBase相關的技術故事/技術實戰經驗,請掃碼關注【騰訊云云開發】公衆號~