1. 程式人生 > >移動端路由層設計

移動端路由層設計

什麼是移動端路由層:

路由層的概念在服務端是指url請求的分層解析,將一個請求分發到對應的應用處理程式。移動端的路由層指的是將諸如App內頁面訪問、H5與App訪問的訪問請求和App間的訪問請求,進行分發處理的邏輯層。

移動端路由層需要解決的問題:

  1. 對外部提供遠端訪問的功能,實現跨應用呼叫響應,包括H5應用呼叫、其他App應用呼叫、系統訪問呼叫等
  2. 原生頁面、模組、元件等定義,統稱為資源(Resource),在跨應用呼叫和路由層在不同端實現的業務表現需要一致的前提下,需要對資源進行定義,在路由提供內部請求分發的時候則可以提供不依賴對外進行資源定義的功能
  3. 外部呼叫如何使用統一標示(Uniform)進行表示資源
  4. 如何在移動端統一定義訪問請求的過程,從而達成移動端與web端的統一性
  5. 如何更好的相容iOS、Android的系統訪問機制、App連結協議、web端路由機制與前端開發規範等
  6. 如何相容各平臺(Android、iOS)App頁面導航機制
  7. 如何解決安全訪問問題
  8. 移動端在客戶端進行動態配置
  9. 移動端路由所應用的場景:

  10. H5頁面與App原生頁面、模組與元件的互動
  11. App與App之間的相互訪問
  12. App內部頁面跳轉、模組排程與元件載入等
  13. 推送與通知系統解除硬編碼的邏輯,動態訪問原生資源,更好的支援通過通知和推送完成動態頁面訪問和邏輯執行
  14. Extension等動態呼叫主App的資源
  15. App實現更復雜的架構MVVM或者是VIPER架構,提供解除業務相互依賴的能力
  16. 以元件化為目的的工程改造,隔離各個業務,以製作單獨的元件

對外如何定義資源

在路由提供對外的資源請求轉發的時候,因為要照顧到其他應用的請求表達方式,比如H5應用或者是其他App的應用的訪問請求,定義單純依賴業務的資源定義就顯得有些必要了。
舉個例子,一個H5的商品詳情頁,被使用者分享,當其他使用者看到這個H5應用的頁面的時候,點選,如果該使用者裝了有對應這個H5商品詳情頁的App的時候,應該跳轉到該App的原生商品詳情頁,如果沒有安裝則載入這個H5頁面,在這個過程中,H5的頁面是通過URL進行標識的,那這個URL的標識也應該對照到App的原生頁面,但是要只依賴業務標識而不能依賴App的程式碼實現,比如說iOS端的App的商品詳情頁叫做DetailViewController,那這個URL是不能包含這個名字的,Android端可能叫DetailActivity,如果不單純依賴業務,那H5應用就要根據平臺來重新發送不同的資源定義的URL,就造成了硬編碼問題,H5應用要依賴App的實現邏輯,如果有一天,原生App的頁面程式碼實現變成了GoodDetailViewController,所有依賴DetailViewController這個資源標示的H5應用都要進行更改,就會出現問題。所以路由層的設計應該具備根據業務定義來對映App內的資源定義。
常常在設計路由層的時候,我們會更加關注通訊行為的細節、如何改進特定通訊機制的表現,常常忽略了一個事實,那就是改變應用程式的互動風格比改變協議對整體的表現有更大的影響。
所謂資源,就是一個應用程式提供的不可分割的服務,從這個層面上看,App的資源即是一種實體的存在,可以進行獲取和訪問,必須進行良好的表示,在有些必要的情況下,必須是獨一無二的識別符來表示一個應用程式所提供的服務是什麼。表示資源我們更傾向於使用URI進行標示,因為移動端沒有一個橫跨iOS、Android、Web後端與H5應用的資源標示方式,而URI是web service模式的資源通用表示方式,包括後面將要提到的Android與iOS統一支援的universal link(通用連結)也是借用URI的概念,App路由層所涉及到的資源表示方法還是建議使用URI的標示方式,同時更應該借鑑RESTful風格來架構這一層,原因是App的頁面、元件或者說一整套功能性的服務是非常複雜的,相比於H5有更加多與複雜的互動,相比於後端存在更加苛刻的網路環境與多裝置多平臺的技術考量,所以URI在標示橫跨多平臺多版本的資源的情況下,能夠更好的表示某一個資源實體而不是資源的表現形式。
在Android與iOS系統中,均支援URL Scheme,所以資源的標示通常會是這個樣子:

12345 AppScheme://path//例如qq app:mqq:// //支付寶:支付寶alipay://

如果協議是Http或者是Https標示的是Web應用或者是H5應用,你的App也是一個與WebService相同級別的應用,那麼URL的協議部分應該是App的唯一標示符,這個主機部分和路徑部分則需要我們使用RESTful的風格進行重新設計。
重點是如何標示資源,例如表示App中的登入服務,那可以表示為:

1 AppScheme://host/login

host為主機部分,在一般的WebService上,在業務表現形式上一般是比較大的業務條線的標示,比方說 https://news.sina.com.cn ,主機部分是news.sina.com.cn,則標示新浪新聞這條業務線,在App內你的業務條線也應該是清晰的,假如移動App的主UI框架是Tab分欄,那麼每個Tab分欄就是你的業務條線的分割,這點跟WebService應用的導航欄類似,App的資源大多是頁面或者是可互動的元件,與UI關係比較大,假如你的Tab有四個:分別叫首頁、商品、發現、我的,那麼我們可以這樣定義:

1234 AppScheme://index/AppScheme://goods/AppScheme://discover/AppScheme://user/

當然,也可以有額外的定義,比方說App有Api服務,Api提供實現一個純資料同步的服務標示,那麼這個URL可以設計為:

1 AppScheme://api-asycn/collections?action='insert'&value='***'&&userUoken='*******'&&source="https//***.***.com/collection.html"

由於RESTful風格強調URL的資源標示而不是行為表示,所以”AppScheme://api-asycn/collections” 是一個良好的資源標示,表示了一個收藏功能的實體,而”?”後面的GET方式的引數實際上是不得已為之,因為實際上沒有Web的http request的實體,所以只能勉強借助GET引數來替代RESTful風格中強調的Accept和Content-Type欄位來標示表現層的行為描述。
當然action與value這樣的描述可以根據業務劃分,但是重點是要用引數表現形式。

iOS與Android的系統訪問機制、統一的連結協議

蘋果的URL Scheme由來已久: Apple URLScheme,Android平臺同樣也實現了該功能,使得App能夠在沙盒機制的前提下,能夠相互呼叫宣告過的服務。由於URL Scheme天生沒有返回的callBack機制,著名的App Drafts的作者聯合Marco Arment、Justin Williams 等人開發了x-callback-URL來做出統一跳轉的協議: x-callback-url,在此不過多表述。
利用URL-Scheme的機制,可以定義如下的統一連結協議:

  1. 協議部分來標示App應用
  2. 主機Host部分用於標示業務線或者是應用提供的劃分好的服務實體,比方說index、discover是業務條線,api-asycn是對外提供的api,pushService是App內部的推送服務等。
  3. 路徑部分則可以是細分的頁面、元件或者服務的標示
  4. 引數定義有一些是必要的,比如說action來標示動作,比方說可以使用get標示獲取、insert增加,userToken表示安全的使用者令牌,source表示來源,當然像是userToken與source這些都是路由層需要進行解析和驗證的,而action則是業務相關的引數,這一點在路由曾設計的時候需要進行詳細區分

    統一訪問請求過程

1124274-17444300670ede7e

route流程圖.png

整個統一的訪問請求過程如圖,關於最後的response返回有一些說明:
在WebService的工作棧中,http的request與response是有標準協議規範的,而App的路由層只是套用的URI的資源標示和RESTFul風格的互動,沒有標準的request和response結構,這部分實現在App內部,response對外部呼叫系統而言關心的有三個重要元素,資源狀態碼、返回值與錯誤,在路由層在響應外部呼叫的時候需要返回這三種元素

路由層邏輯結構1224274-a9c3f54870c7511b

App Route邏輯結構圖.png

路由層安全

路由層的安全包含兩個方面:

  1. 跨應用時,需要注意注入攻擊,做到敏感引數加密防篡改,同時需要注意路由層應提供能夠實現風控的機制
  2. 跨業務系統的時候,需要開啟會話訪問機制,通過令牌或者是session會話等來實現路由層身份認證

    路由層實現

    敬請期待下一篇文章:《一步步構建iOS路由》

    番外:App孤島、API經濟與App開放性討論

    什麼叫App孤島

    移動作業系統中的App一般都採用沙盒機制來嚴格限制訪問許可權,App與App之間是不通的,使用者往往會安裝大量的App,比方說找吃飯的地方是大眾點評,聊天是微信,地圖是高德等等,那麼我們想象一下沒有URL Scheme的世界,你在大眾點評上找到了一個好吃的地方,然後需要切換到高德去找找在哪,然後腦子記錄下來地址然後在微信上發給你的朋友,這麼一個過程中,眾多App之間是不能傳遞資訊和相互協作的,那一個個App就成了資訊孤島,給使用者帶來極大的不便,而實現了URL Scheme的App一般都是大廠,使用者過億,給上億人帶來了方便。

    打破App孤島

    本質上URL Scheme是作業系統支援的,也就是說,打破App孤島,必須過作業系統這一關,而無論是第三方開發者還是Apple與Google都在努力打破資訊孤島。
    Apple與Google分別在iOS9與Android M支援了universal link以打通H5應用和原生應用的屏障。
    Apple則在iOS作業系統中通過Spotlight應用內搜尋、AppGroups、AppExtension、ShareExtension與SiriKit等打破原生應用之間的資訊屏障。
    Google則通過PWA希望替代原生應用來實現大一統。
    第三方開發者們也積極推動著這一趨勢。比如說:
    前面提到的著名的App Drafts的作者聯合Marco Arment、Justin Williams 等人開發了x-callback-URL來做出統一跳轉的協議: x-callback-url,希望大部分App開發者能夠響應號召,更好的進行開發。
    國內的一些深度連結的開發者平臺 DeepShare – Share your App with the world
    錘子手機開源的onestep等等。
    作為一名開發者,構建安全高效而開放的路由實際上不僅僅滿足技術架構的需求更能為打破App孤島,更好的發展移動端生態做出貢獻。

    什麼叫做API經濟

    API經濟是基於API所產生的經濟活動的總和,在當今發展階段主要包括API業務,以及通過API進行的業務功能、效能等方面的商業交易。API經濟是當今各行業(零售、金融、物聯網、醫療等)中驅動數字變革的主要力量。 ———百度百科

為什麼這裡需要談到API經濟呢?我們都知道經濟學的第一要務是效率優先原則,就像上面我們聊到的App孤島,在日益便利的移動化時代,實際上降低了資訊共享的效率,而增加了使用者的操作成本,則會阻礙這個平臺上使用者的活躍度,那上層利用移動平臺的可能性就會被限制。比如,二維碼和NFC解決了pos終端、商家與支付App之間的資訊共享問題,就導致了繁盛的線下支付經濟,同樣的道理,各系統之間無論是App、WebServices或者是其他應用能夠開放API則會形成平臺或者產業上的資訊共享的規模效應,則會形成良性發展。
作為App開發者,你需要實現路由這一層,才能夠支援跨應用之間的呼叫,才能放開你想開發的API。
如果一個App的後端Services能夠和App一起開放API,那則更加具有優勢。比方說微信,如果開放了收藏的WebService API介面,同時微信App也開放URLScheme的收藏介面,那麼無論在瀏覽器、手機中都能無縫實現隨時隨地的收藏一切內容,極大的方便使用者。

App開放性討論

這個環節主要是討論開放的時候要注意哪些:

  1. App型別(決定要不要開放)
  2. 路由安全(決定開放程度)
  3. 開放時機
    未完,希望大家多多評論,一起討論。