falcor掃盲篇

ggd543發表於2018-07-31

本文目的是介紹falcor的基本概念和工作原理,並演示如何在egg應用中引入falcor,使得讀者能快速掌握falcor的基本用法。

falcor是什麼

falcor是介於客戶端和服務端的資料中介軟體. 它把整個應用的域模型通過一個虛擬JSON物件表示,並抽象出get, set和call三種操作,使得應用程式可以用一種一致的方式讀寫域模型的資料,同時不用關注資料的來源。此外,falcor還提供了快取、批量打包和去重的功能,從而減少了網路請求和往返的次數以及冗餘資料的儲存和傳輸.

三大特徵

單一域模型(One model everywhere)

falcor把整個應用的域模型通過一個虛擬的Json Graph來表示(你可以暫且把這個Json Graph理解成一個大JSON物件). 這麼做的好處是 業務方無需關心資料的來源, 即資料可能儲存在客戶端記憶體,資料庫或某個網路節點,可以更專注業務邏輯的實現.

資料即API(The data is the api)

falcor在JSON Graph之上抽象了三種操作:get, set和call,分別對應著讀取,寫入和呼叫。由於所有對域模型的CRUD最終都通過這3種操作來表達,因此只要域模型的資料結構(即Json Graph)的結構被確定下來,那麼就可以隨心所欲的對域模型進行CRUD,無需額外定義一套API。

雲端繫結(Bind to the cloud)

直接翻譯過來不好理解。

實際上想表達的意思是,由於引入了Json Graph的概念,使得同一個實體(entity)可以通過唯一的路徑來指定,並通過引用(Reference)間接表示. Falcor會自動遍歷Json Graph中的引用並在需要的時候發出請求, 然後將其引用替換為真實的實體物件。同時,falcor會透明地處理所有的網路通訊,並實現批處理和去重。

基本概念

為了能更好的理解和使用falcor, 需要了解一些基本概念

Json Graph

Json Graph是以Json物件來表達圖資訊(Graph Infomation)的一種規約。falcor使用Json Graph來表示域模型. 這麼說有點抽象,看一個Json Graph例子。

{
    todosById: {
        "44": {
            name: "get milk from corner store",
            done: false,
            author: {  
                    $type: `atom’,
                    value: { firstName: `Liu`, lastName: `Archer` }
            },
            prerequisites: [{ $type: "ref", value: ["todosById", 54] }]
        },
        "54": {
            name: "withdraw money from ATM",
            done: false,
            prerequisites: []
        }
    },
    todos: [
        { $type: "ref", value: ["todosById", 44] },
        { $type: "ref", value: ["todosById", 54] }
    ]
}

JSON Graph本質上也是JSON物件,因此可以使用任何json解析器進行解析。 只不過,falcor為JSON
Graph引入了3種新的原生型別:引用(ref), 原子(atom)和錯誤(error). 並提供了一組工具用於轉換、儲存和獲取這些資料, 在上面的例子,todos陣列包含兩個元素,這兩個元素都通過引用來表達,其中todoById[44].author被定義atom型別,因此它將會被falcor當做一個整體看待。

Paths

一組鍵(key)的有序序列,用於定位Json Graph中某個屬性。比如有如下的Json Graph

{
    todos: [
      {
        name: `get milk from corner store`,
        done: false
      }
    ]
  }

要獲取todos陣列的第一個元素中的name屬性,則需要提供這樣的Path: todos[0].name,或者用陣列的形式表示: [‘todos`, 0, `name’]

Path總是從json Graph的根開始解析的

PathSets

PathSets就是若干Path的集合。Falcor允許同時從json graph中獲取多個屬性

DataSource

資料來源是實現了JSON Graph三種抽象操作的介面。每個資料來源有且僅關聯一個JSON Graph

Model

Model可以理解為JSON Graph的高階介面。實際上,Model在Data Source之上,提供了快取和格式轉換等一系列的功能。這張圖比較清晰的表達了 Model 和 DataSource的關係

image.png

Router

Model是工作在客戶端的,如果Model需要從服務端獲取資料,必須經過Router進行代理。

falcor的工作原理

image.png

falcor由客戶端和服務端兩部分構成。前端應用通過提供一組Paths(或PathSets), 呼叫Model的相關操作(get , set或call)完成資料的讀寫或其他處理。Model會自行解析Path,並將操作派發給DataSource執行,而部分操作可能需要交由服務端的Router ,最後Model彙總所有結果並返回。期間,model會做一些優化,比如快取優化,請求合併等.

如何引入falcor

服務端

falcor 為express 和 koa應用提供了路由適配,見[falcor-kao-router]和[falcor]。 下面說一下如何在egg應用中引入falcor。

首先安裝falcor-routefalcor-koa-routerfalcor-json-graph

npm i -S falcor-router falcor-koa falcor-json-graph

falcor-json-graph不是必須的,它是一個用於生成json graph片段的輔助庫。但一般會使用它減少編碼複雜度

接著定義falcor路由。為了和egg controller區別開來,建議把falcor路由檔案放到app/falcor目錄下

// app/falcor/index.js

const router = require(`falcor-koa-router`);

module.exports = router.routes([
    {
       route: `greeting`,
       * get() {
           // this 指向 egg application
           const ctx = this.ctx;
           return dataMock.greeting(ctx);
        }
    },
    // more falcor routes
]);

最後在app/router.js加入falcor路由

// app/router.js

const falcorRouter = require(`./falcor/index`);

module.exports = app => {
  router.all(`/model.json`, falcorRouter);
  // more egg routes
};

客戶端

  1. UMD方式。

在頁面上通過<script>標籤引入falcor.browser.js

  <script src="https://netflix.github.io/falcor/build/falcor.browser.js"></script>

然後通過window.falcor引用

var model = new window.falcor.Model({
      source: new falcor.HttpDataSource(`/model.json`, {
        timeout: 60000,
      })
    });
model.getValue(‘/greeting’).then(e => console.log(e));
  1. CMD方式,,

安裝falcor依賴

npm i -D falcor

通過requireimport方式匯入falcor

var falcor = require(`falcor`);

最後通過構建工具(如webpack等)打包到jsbundle

完整的egg-falcor例子見 這裡

其他資源

常用的庫


相關文章