小程式·雲開發的雲函式路由高階玩法

lcxfs1991發表於2018-09-21

概念回顧

在掘金開發者大會上,在推薦實踐那裡,我有提到一種雲函式的用法,我們可以將相同的一些操作,比如使用者管理、支付邏輯,按照業務的相似性,歸類到一個雲函式裡,這樣比較方便管理、排查問題以及邏輯的共享。甚至如果你的小程式的後臺邏輯不復雜,請求量不是特別大,完全可以在雲函式裡面做一個單一的微服務,根據路由來處理任務。

用下面三幅圖可以概括,我們來回顧一下:

比如這裡就是傳統的雲函式用法,一個雲函式處理一個任務,高度解耦。

第二幅架構圖就是嘗試將請求歸類,一個雲函式處理某一類的請求,比如有專門負責處理使用者的,或者專門處理支付的雲函式。

最後一幅圖顯示這裡只有一個雲函式,雲函式裡有一個分派任務的路由管理,將不同的任務分配給不同的本地函式處理。

tcb-router 介紹及用法

為了方便大家試用,我們們騰訊雲 Tencent Cloud Base 團隊開發了 tcb-router,雲函式路由管理庫方便大家使用。

那具體怎麼使用 tcb-router 去實現上面提到的架構呢?下面我會逐一舉例子。

架構一:一個雲函式處理一個任務
這種架構下,其實不需要用到 tcb-router,像普通那樣寫好雲函式,然後在小程式端呼叫就可以了。

  • 雲函式
  • 小程式端

架構二: 按請求給雲函式歸類
此類架構就是將相似的請求歸類到同一個雲函式處理,比如可以分為使用者管理、支付等等的雲函式。

  • 雲函式
  • 小程式端

架構三: 由一個雲函式處理所有服務

  • 雲函式
  • 小程式端

借鑑 Koa2 的中介軟體機制實現雲函式的路由管理

小程式·雲開發的雲函式目前更推薦 async/await 的玩法來處理非同步操作,因此這裡也參考了同樣是基於 async/await 的 Koa2 的中介軟體實現機制。

從上面的一些例子我們可以看出,主要是通過 userouter 兩種方法傳入路由以及相關處理的中介軟體。

use 只能傳入一箇中介軟體,路由也只能是字串,通常用於 use 一些所有路由都得使用的中介軟體

router 可以傳一個或多箇中介軟體,路由也可以傳入一個或者多個。

不過,無論是 use 還是 router,都只是將路由和中介軟體資訊,通過 _addMiddleware_addRoute 兩個方法,錄入到 _routerMiddlewares 該物件中,用於後續呼叫 serve 的時候,層層去執行中介軟體。

最重要的執行中介軟體邏輯,則是在 servecompose 兩個方法裡。

serve 裡主要的作用是做路由的匹配以及將中介軟體組合好之後,通過 compose 進行下一步的操作。比如以下這段節選的程式碼,其實是將匹配到的路由的中介軟體,以及 * 這個通配路由的中介軟體合併到一起,最後依次執行。

組合好中介軟體後,執行這一段,將中介軟體 compose 後並返回一個函式,傳入上下文 this 後,最後將 this.body 的值 resolve,即一般在最後一箇中介軟體裡,通過對 ctx.body 的賦值,實現雲函式的對小程式端的返回:

那麼 compose 是怎麼組合好這些中介軟體的呢?這裡擷取部份程式碼進行分析

看完這裡的程式碼,其實有點疑惑,怎麼通過 Promise.resolve(handler(xxxx)) 這樣的程式碼邏輯可以推進中介軟體的呼叫呢?

首先,我們知道,handler 其實就是一個 async functionnext,就是 dispatch.bind(null, i + 1) 比如這個:

而我們知道,dispatch 是返回一個 Promise.resolve 或者一個 Promise.reject,因此在 async function 裡執行 await next(),就相當於觸發下一個中介軟體的呼叫。

compose 完成後,還是會返回一個 function (context, next),於是就走到下面這個邏輯,執行 fn 並傳入上下文 this 後,再將在中介軟體中賦值的 this.body resolve 出來,最終就成為雲函式數要返回的值。

看到 Promise.resolve 一個 async function,許多人都會很困惑。其實撇除 next 這個往下呼叫中介軟體的邏輯,我們可以很好地將邏輯簡化成下面這段示例:

相關文章