我想獨立實作一個全棧産品為什麼這麼難
日常生活中,我們會使用很多軟體産品。在使用這些産品的時候,我們看得見的東西稱為“前端界面”如一個輸入框、一個按鈕,點選按鈕之後發生的一切看不見的東西稱為“後端服務”。與之對應的創造者分别稱為“前端程式員”、“後端程式員”,然而,一個完整産品的開發不僅僅是隻有前端和後端,還有設計師,架構師,運維等。有沒有可能這些所有的事情都一個人幹呢?有可能,事實上如今就有很多的“全棧工程師”,他們身兼數職,是多面手。能獨立完成一個産品的方方面面。這種人固然十分了得,他們通常具有多年的經驗,涉獵廣泛,是老手,也是高手,當有一個産品想法的時候,他們可以用自己的全面專業技能,盡情的發揮去實作自己的想法。是以,從某種意義上講“全棧也是一種自由”,你可以自由的實作你的想法,這簡直太美妙了!
然而,很多時候當我們有一個産品想法的時候,我們往往發現,前端寫完了,後端怎麼搞?資料庫怎麼搞?域名怎麼搞?域名還要備案?應用部署怎麼搞?我的買什麼樣的伺服器啊?靜态資源 CDN 怎麼搞?檔案上傳伺服器怎麼搞?萬一通路使用者多了能撐住嗎?等等……問題很多,導緻你的一個個想法,都隻是在腦海中昙花一現,從來都無法将她們實作,或者說你激情飽滿的實作了其中自己最擅長的一部分,當碰到其他難題的時候就止步了。于是仰天長嘯:我就想獨立做一個完整的産品為什麼這麼難?年輕人,這一切都不怪你……
破局:小程式雲開發
為什麼使用小程式雲開發來破局?
為啥是用“小程式雲開發”來破局?首先,我們的目的是全棧實作一個産品。全棧可以有多種技術方案,你可用任何你能會的技能來達到全棧的目的。你可以開發安卓,IOS,或者 PC 站,然而小程式是最實際的!為啥?手機上能做的事情為啥要用 PC 版?OK,既然手機版比較好,那能不能再簡單一點?能,就是小程式,不需要開發IOS,安卓兩個版本。可以快速産出,快速試錯。
其次,前面說到了,全棧實作一個産品并不容易,對很多人來說甚至是巨難!選擇了小程式已經是比較劃算的方案。而再內建雲開發,全棧立馬就有了。這就是為什麼選擇“小程式雲開發”來破局。
小程式雲開發是什麼?
小程式雲開發是什麼?官方文檔是這麼說的:開發者可以使用雲開發開發微信小程式、小遊戲,無需搭建伺服器,即可使用雲端能力。雲開發為開發者提供完整的原生雲端支援和微信服務支援,弱化後端和運維概念,無需搭建伺服器,使用平台提供的 API 進行核心業務開發,即可實作快速上線和疊代,同時這一能力,同開發者已經使用的雲服務互相相容,并不互斥。
看完上面的描述,也許你仍然無法非常清楚的知道什麼是“小程式雲開發”,沒關系,你隻需要注意加粗的部分,大概知道它“無需搭建伺服器”,從傳統觀念将,這個似乎“毀三觀”咋可能沒伺服器啊?是的,可以沒有傳統意義上的伺服器,這種模式是 serveless 的。
那麼,小程式雲開發提供了哪些東西來破局呢?且看下面的表格:
能 力 | 作 用 | 說 明 |
---|---|---|
雲函數 | 無需自建伺服器 | 在雲端運作的代碼,微信私有協定天然鑒權,開發者隻需編寫自身業務邏輯代碼 |
資料庫 | 無需自建資料庫 | 一個既可在小程式前端操作,也能在雲函數中讀寫的 JSON 資料庫 |
存儲 | 無需自建存儲和 CDN | 在小程式前端直接上傳/下載下傳雲端檔案,在雲開發控制台可視化管理 |
雲調用 | 原生微信服務內建 | 基于雲函數免鑒權使用小程式開放接口的能力,包括服務端調用、擷取開放資料等能力 |
上面的表格中提到了“雲開發”中的一些能力:“雲函數”,“資料庫”,“存儲”,“雲調用”,我們可以将這些詞帶入你曾經開發過的應用,看看它們分别代表了哪些部分。對于程式員來說,如果有疑問的話,沒有什麼是一個 helloword 解決不了的。
實戰:獨立開發一個簡易的零售小程式
哆嗦再多,不如實戰。下面我們就來使用小程式雲開發實作一個簡單的零售小程式。
項目構思
既然是一個零售小程式,那麼我們可以思考一下零售小程式的大緻業務流程,以及粗略的梳理一下,其功能點。現根據自己的想法,大緻畫一下草圖,如果沒有靈感可以參考一下别的 APP 是如何設計的。
我根據自己的想法設計之後是這樣的:
功能子產品:首頁,商品清單頁,購物車,确認訂單,個人中心,個人訂單,管你子產品(商品添加,分類添加)其中商品需要上傳圖檔。
梳理完功能之後,我們對于要實作的東西已經有個初步的概念了。接下來,我們需要大概畫一下頁面設計、及功能流轉。初次設計可能沒有太多經驗,沒關系,開始做就行了,做着做着就會想法越來越多,然後優化的越來越好。。我也是經過了多番修改調整,最終找到了一些思路。我的(拙劣)設計如下,圖檔如果看不清楚可複制圖檔連結在新視窗打開檢視:
說明,以上圖檔是根據成品(我真的開發了一個雲小程式并上線使用了)截圖的,而實際我再設計的時候也是經過幾番修改才最終定成這樣。
同時,補充說明一下,這裡前端頁面使用的是 vant-weapp控件,非常好用。推薦!如果你和我一樣是一個純後端程式員,建議使用 vant-weapp 來作為 ui,非常友善。否則自己寫頁面樣式的話可能就做不出來了。全棧不是那麼好幹的啊。選擇自己能駕馭的,能實作最終功能,就是一個合格的全棧。
建立小程式雲開發項目
我們先下載下傳微信小程式開發工具,下載下傳位址在這裡,安裝好了之後,建立項目,界面如下,APPID 需要你自己去注冊一個。然後注意,選擇“小程式雲開發”,如下圖所示:
建立好了之後,項目目錄如下,先看 1 标注的地方:
如果你曾經有過小程式的開發經驗,那麼
miniprogram
檔案夾下面的結構你肯定熟悉了,
miniprogram
下面的子目錄分别是小程式對應的元件、圖檔、頁面、樣式以及
app.js
,
app.json
sitemap.json
,其中
components
下面的
vant-weapp
就是上面提到的 ui 元件。
最後一個比較重要的檔案夾就是
cloudfunctions
,這個目錄是用來存放“雲函數的”,雲函數就是我們的後端。每一個雲函數提供一個服務。一個個的雲函數組成了我們整體的後端服務。雲函數可以看做是 FaaS(function as a service)。途中,2 标記的位置的“雲開發”按鈕,我們點進去,就可以看到“雲開發的控制台”,如下圖所示:
如果上圖看不清楚,可以複制連結到新的浏覽器視窗檢視,如圖,小程式雲開發預設的免費套餐有一定的額度可供使用。首頁便是使用統計。然後我們能看到,有“資料庫”,“存儲”,“雲函數”。
這裡的“資料庫”其實就是類似于一個 MongoDB,你可以點進去建立一個個的 collection(即:關系型資料庫中的table);這裡的“存儲”其實就是“檔案夾”,我們可以通過微信提供的 api把圖檔上傳到“存儲”中;這裡的“雲函數”就是我們需要實作的後端業務邏輯,他就是一個個的函數(函數由我們自己寫好後上傳)。一般開發過程中我們在開發者工具中的
cloudfunctions
目錄下建立雲函數(比方說是:user-add)開發完成之後在雲函數目錄點選右鍵——上傳即可。然後就可以在小程式的代碼中調用這個
user-add
雲函數。
雲開發之——3 分鐘實作檔案上傳
注意:在開始雲開發之前,我們現在 小程式代碼的 app.js 中加入
wx.cloud.init
,如下:
App({
onLaunch: function () {
if (!wx.cloud) {
console.error('請使用 2.2.3 或以上的基礎庫以使用雲能力')
} else {
wx.cloud.init({
// env 參數說明:
// env 參數決定接下來小程式發起的雲開發調用(wx.cloud.xxx)會預設請求到哪個雲環境的資源
// 此處請填入環境 ID, 環境 ID 可打開雲控制台檢視
// 如不填則使用預設環境(第一個建立的環境)
env: 'your-env-id',
traceUser: true,
})
}
this.globalData = {}
}
})
上面的圖中,我們已經看到了“商品添加”頁面的效果,它需要我們輸入商品名稱、價格、并上傳圖檔,然後儲存。傳統架構中,上傳圖檔需要前端頁面擺一個控件,然後後端提供一個 api用來接收前端傳來的檔案,通常來說這個後端 api 接收到圖檔之後,會将圖檔檔案儲存到自己的檔案伺服器或者是阿裡雲存儲、或者是七牛雲存儲之類的。然後傳回給你一個檔案連結位址。非常麻煩,然而,小程式雲開發上傳檔案超級簡單,上代碼:
頁面代碼:
<van-notice-bar
scrollable="false"
text="釋出商品"
/>
<van-field
value="{{ productName }}"
required
clearable
label="商品名稱"
placeholder="請輸入商品名稱"
bind:change="inputName"
/>
<van-field
value="{{ productPrice }}"
required
clearable
label="價格"
icon="question-o"
bind:click-icon="onClickPhoneIcon"
placeholder="請輸入價格"
error-message="{{phoneerr}}"
border="{{ false }}"
bind:change="inputPrice"
/>
<van-action-sheet
required
show="{{ showSelect }}"
actions="{{ actions }}"
close-on-click-overlay="true"
bind:close="toggleSelect"
bind:select="onSelect" cancel-text="取消"
/>
<van-field
value="{{ productCategory }}"
center
readonly
label="商品分類"
border="{{ false }}"
use-button-slot
>
<van-button slot="button" size="small" plain type="primary"
bind:click="toggleSelect">選擇分類</van-button>
</van-field>
<van-button class="rightside" type="default" bind:click="uploadImage" >上傳商品圖檔</van-button>
<view class="imagePreview">
<image src="{{productImg}}" />
</view>
<van-submit-bar
price="{{ totalShow }}"
button-text="送出"
bind:submit="onSubmit"
tip="{{ false }}"
>
</van-submit-bar>
<van-toast id="van-toast" />
<van-dialog id="van-dialog" />
這裡有個控件,綁定了
uploadImage
方法,其代碼為:
uploadImage:function(){
let that = this;
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success(res) {
wx.showLoading({
title: '上傳中...',
})
const tempFilePath = res.tempFilePaths[0]
const name = Math.random() * 1000000;
const cloudPath = name + tempFilePath.match(/\.[^.]+?$/)[0]
wx.cloud.uploadFile({
cloudPath:cloudPath,//雲存儲圖檔名字
filePath: tempFilePath,//臨時路徑
success: res => {
let fileID = res.fileID;
that.setData({
productImg: res.fileID,
});
wx.showToast({
title: '圖檔上傳成功',
})
},
fail: e =>{
wx.showToast({
title: '上傳失敗',
})
},
complete:()=>{
wx.hideLoading();
}
});
}
})
}
這裡,
wx.chooseImage
用于調起手機選擇圖檔(相冊/相機拍照),然後
wx.cloud.uploadFile
用于上傳圖檔到上面說到的雲開發能力之一的“存儲”中。上傳圖檔成功之後傳回一個檔案 ID,類似:
cloud://release-0kj63.7265-release-0kj63-1300431985/100477.13363146288.jpg
這個連結可以直接在小程式頁面展示:
<image src="cloud://release-0kj63.7265-release-0kj63-1300431985/100477.13363146288.jpg " />
也可以通過微信 api,裝換成 http 形式的圖檔連結。
雲開發之——操作資料庫,1 分鐘寫完儲存商品到資料庫的代碼
上面我們實作了商品圖檔上傳,但是,商品圖檔并沒有儲存到資料庫。正常錄入商品的時候,我們會填好商品名稱,價格等,然後上傳圖檔,最終點選“儲存”按鈕,将商品儲存到資料庫。傳統模式下,前端仍然是需要調用一個後端接口,通過 post 送出資料,最終由後端服務(比如 java 服務)将資料儲存到資料庫。小程式雲開發使得操作資料庫十分簡單,首先我們在雲開發控制台建立“商品表”,即一個
collection
,取名為:
products
。然後我們就可以儲存資料到資料庫了,代碼如下:
onSubmit:function(){
// 校驗代碼,略
let product = {};
product.imgId = this.data.productImg;
product.name= this.data.productName;
product.categoryId = this.data.productCategoryId;
product.price = this.data.productPrice;
// 其他指派,略
const db = wx.cloud.database();
db.collection('products').add({
data: product,
success(res) {
wx.showToast({
title: '儲存成功',
})
}
});
}
以上就實作了資料入庫,就這點代碼,超簡單,1 分鐘寫完,誠不欺我。其中這裡的
products
就是我們的“商品表”,之前說過,類似 MongoDB 資料庫,這裡操作的是
db.collection
,這和 MongoDB 的文法差不多。
雲開發之——使用雲函數完成後端業務邏輯,訂單建立
小程式雲開發提供了幾大能力:“資料庫”,“存儲”,“雲函數”,前兩項我們已經有所體會了。下面我們能建立一個雲函數來實作訂單建立。這裡說明,雲函數其實就是 一段JavaScript 代碼,上傳至雲伺服器之後,最終也是運作在 nodejs 環境的,隻是這一切,我們不需要關心。我們隻需要關心我們這個雲函數提供的功能是什麼就可以了。
建立雲函數很簡單,直接在開發工具中右鍵“建立Node.js 雲函數”。然後以建立訂單為例,假設我們建立一個雲函數名為
c-order-add
,建立好了之後,目錄是這樣:
雲函數的主要代碼在 index.js 中,其完整代碼是這樣:
// 雲函數入口檔案
const cloud = require('wx-server-sdk')
cloud.init({
env: 'release-xxx'// your-env-id
})
const db = cloud.database()
// 雲函數入口函數
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext();
console.log("雲函數 c-order-add : ")
// 這裡是一些邏輯處理...
return await db.collection('uorder').add({
data: {
openid: event.userInfo.openId,
address: event.address,
userName: event.userName,
phone: event.phone,
shoppingInfo: event.shoppingInfo,
totlePrice: event.totlePrice,
shoppingStr: event.shoppingStr,
remark:event.remark,
createTime: now,
// ...
}
});
}
這個雲函數寫好之後,需要上傳到伺服器,直接在雲函數目錄點選右鍵,然後點選“上傳并部署”即可,這就相當于部署好了後端服務。前端小程式頁面調用的寫法是這樣的:
let orderData={};
orderData.userName = this.data.userName;
orderData.phone = this.data.phone;
orderData.address = this.data.address;
// ....
wx.cloud.callFunction({
// 雲函數名稱
name: 'c-order-add',
// 傳給雲函數的參數
data: orderData,
complete: res => {
Dialog.alert({
title: '送出成功',
message: '您的訂單成功,即将配送,請保持手機通暢。'
}).then(() => {
// ....
wx.redirectTo({
url: '../uorder/uorder'
});
});
}
})
這裡,向程式前端,通過
wx.cloud.callFunction
完成了對雲函數的調用,也可以了解為對後端服務的調用。至此我們我們介紹完了,小程式雲開發的功能。雖然,我隻貼出了少量的代碼,即儲存商品,和送出訂單。由于時間和篇幅有限,我不可能把整個完整的程式代碼貼出來。但是你可以參照這個用法示例,将剩下的業務邏輯補充完整,最終完成“項目構思”一節中展示的成品截圖效果。
小程式稽核的一點經驗
我開發的小程式稽核在送出稽核的時候遭遇了兩次退回,第一次是因為:“小程式具備電商性質,個人小程式号不支援”。是以,我隻好申請了一個企業小程式号,使用的是超市的營業執照。服務類目的選擇也被打回了一次,最後選擇了食品還送出了食品經營許可證。第二次打回是因為:“使用者體驗問題”。其實就是“授權索取”的問題,微信不讓打開首頁就“要求授權”,同時不能強制使用者接受授權,得提供拒絕授權也能使用部分功能。
上面兩條解決之後,更新新了好幾版,都沒有出現過被拒的情況。并且,有次我是夜晚 10 左右提價的稽核,結果10 點多就提示稽核通過,當時沒看具體時間,就是接盆水泡了個腳的時間稽核通過了。是以,我推斷小程式稽核初次稽核會比較嚴,之後如果改動不大應該直接機審就過了。
總結及對比
這裡我們可以對小程式雲開發和傳統模式做一個對比:
對比條目 | 傳統模式 | 雲開發 |
---|---|---|
是否需要後端服務 | 需要 (如一個java應用部署在 Tomcat 中) | 不需要 隻需要“雲函數” |
是否需要域名 | 需要 (還得在微信背景的把域名加入安全域名) | 不需要 |
是否需要購買伺服器 | 需要 (你得部署後端 Java 應用,還得安裝資料庫) | 不需要 開通雲開發之後免費套餐夠用 不夠的話購買套餐按調用量計費 |
是否需要懂運維 | 需要 (你得會折騰伺服器,資料庫之類的 還得配置好相關的使用者,端口,啟動服務) | |
圖檔上傳及 CDN | 麻煩 | 簡單 |
擷取微信 openID | 超級簡單,雲函數中直接擷取 | |
··· |
就對比這麼多吧,總之,我非常喜歡小程式雲開發,小程式真的可以讓你輕松幹全棧。或者咱們别動不動就提“全棧”,姑且說,小程式雲開發可以讓你更簡單、更快速、更便宜的實作你的産品落地。我自己開發的雲小程式上線之後,使用了一兩個月,沒出現任何問題。我也不用操心伺服器什麼的。是以,我已經給身邊很多人安利了小程式雲開發了。這裡我就不貼出我的小程式碼了,因為已經正式給我同學的超市使用了,是以不友善讓别人去産生測試資料。如果你感興趣想看的話,可以聯系我。郵件[email protected]
Docker & k8s 系列一:快速上手docker
Docker & k8s 系列二:本機k8s環境搭建
Docker & k8s 系列三:在k8s中部署單個服務執行個體
感謝您的閱讀,歡迎您評論交流。PS:部落格園已停更,後續請通過郵件或者公衆号聯系