低程式碼平臺中的資料連線方式(上)

語言: CN / TW / HK

1. 前言

在早幾年,“拖拽式 H5 營銷頁製作工具” 曾經是前端界的一大熱門方向,這類工具的特點是可以通過拖拽的方式來生成帶有各種酷炫效果的靜態營銷頁,這類工具可以看作是現今“低程式碼平臺”的前代產品。

而在當今的網際網路中,以 “靜態” 方式承載內容的頁面越來越少。也就是說,“拖拽生成靜態頁”這樣單純的能力在現代應用的開發過程中能覆蓋的場景是非常少的,這就催生了以 “能夠對接動態資料” 為特徵的第二代低程式碼產品。

為了滿足 “對接動態資料” 這一基礎訴求,低程式碼平臺經歷了從最初簡單 API 對接模式到完整的資料模型接管的發展過程,而完整的資料模型接管能力,也是現今各低程式碼廠商發力深耕的方向之一。

低程式碼平臺中可選的資料連線方式有很多種,各種方法產生和成熟的時期不同。而在現今網際網路主流的業務模式下,這些方法在不同的場景下都有其適用的範疇。

關於低程式碼平臺的資料鏈接方式這個話題,我們將分為上下兩篇內容進行分享:

  • 在(上)篇中,我們將介紹 經典的單 API 通訊資料連線方式 - 簡單的單 API 連線方式存在的問題 - 相應解決方案

  • 在(下)篇中,我們將介紹在低程式碼時代發展起來的 API 編排 - FaaS - 資料庫直連等新型方案

2. 傳統手工模式下動態資料的獲取和渲染

在網際網路頁面開發中,動態資料的獲取 - 渲染可以說是一個最基本的 “需求”。在多數情況下,當瀏覽器向服務端請求一個頁面的時候,服務端返回的會是一個頁面的 “框架”,而頁面的具體內容會由頁面中的 JavaScript 指令碼向服務端發起 ajax 請求並將返回結果渲染到頁面上。

在 jQuery 盛行時期的網際網路開發中,“從服務端獲取資料並渲染到頁面上” 的程式碼可能是這樣的(程式碼示例來源:jQuery官網, http://api.jquery.com/jquery.ajax/):

var menuId = $( "ul.nav" ).first().attr( "id" );
var request = $.ajax({
url: "script.php",
method: "POST",
data: { id : menuId },
dataType: "html"
});


request.done(function( msg ) {
$( "#log" ).html( msg );
});


request.fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});

而在 MVVM 框架經過數年角逐並形成 React / Vue 二分天下之勢力的當今網際網路開發中,“從服務端獲取一段資料並在頁面中渲染出來” 的程式碼可能是這樣(React,程式碼示例來源:http://dev.to/antdp425/react-fetch-data-from-api-with-useeffect-27le)

// 1. Import *useState* and *useEffect*
import React, {useState, useEffect} from 'react';
import './App.css';


function App() {
// 2. Create our *dogImage* variable as well as the *setDogImage* function via useState
// We're setting the default value of dogImage to null, so that while we wait for the
// fetch to complete, we dont attempt to render the image
let [dogImage, setDogImage] = useState(null)


// 3. Create out useEffect function
useEffect(() => {
fetch("http://dog.ceo/api/breeds/image/random")
.then(response => response.json())
// 4. Setting *dogImage* to the image url that we received from the response above
.then(data => setDogImage(data.message))
},[])


return (
<div className="App">
{/* 5. Using *dogImage as* the *src* for our image*/}
{dogImage && <img src={dogImage}></img>}
</div>
);
}


export default App;

或這樣(Vue,程式碼示例來源:http://cn.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html)

new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get('http://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
}
})

無論是早期 jQuery 還是現今已經成為網際網路頁面基礎設施的 MVVM 框架,“動態資料連線” 的方式大抵是 “向某個後端介面傳送請求然後等待資料返回”。

而在進行前端業務元件的 “低程式碼” 形式封裝時,低程式碼框架和平臺的建設者們第一步做的通常也是將元件需要的 API 請求抽取成配置項。

3. 低程式碼最初的資料連線方式 

—— 通過 API URL 進行資料通訊

如圖 1 中的 CRUD 元件,在元件配置中填寫資料列表的獲取介面和新增資料提交介面後,元件初始化時會向填寫的 API 發起網路請求,新增記錄時也會使用配置的新增資料提交介面。

這樣一來,通過一個簡單的配置項就能夠實現原本需要書寫大段程式碼的功能。

圖 1  為 CRUD 元件配置非同步請求介面

這種通過 API 配置即可實現資料連線的方案,很簡單也很美好,在低程式碼平臺建設的初期往往也會被作為 “最小可用版本” 的首選方案。

但是在實際落地場景中,這種最簡單的方案往往會遇到兩個問題:

    • 一是前端需要的資料格式和後端返回的資料格式不匹配的問題。

    • 二是前端最經典的問題 —— 跨域問題。

下面我們結合低程式碼平臺在實際落地中的場景來看一看上述兩個問題的產生緣由。

4. 問題產生 —— 低程式碼平臺實際落地中的阻礙

    4.1 前後端資料格式不匹配問題

在低程式碼平臺實際業務落地的過程中,多數時候面對的場景都不是 “從零開始” 用低程式碼平臺去搭建一個應用,而是 “將某些業務模組逐步遷移到低程式碼平臺”。這就意味著低程式碼平臺需要和許多已經在線上執行的舊介面打交道。

在業務逐步往低程式碼遷移的過程中,很長一段時間內可能是如圖 2 所示的狀態 —— 低程式碼平臺需要去連線一些仍在支援線上業務的介面,同時這些介面也仍在支撐著執行中的線上業務,這就意味著不能為了 “接入低程式碼平臺” 而貿然對這些介面進行改造。

圖 2  低程式碼平臺連線現有的舊介面

而從低程式碼平臺中的角度來說,通用元件為了保證其通用性,必然需要對介面返回的資料格式有一個統一的規約。例如在 低程式碼平臺愛速搭 的元件體系(即 AMIS)中,就規定了資料介面的返回格式需要符合以下格式,可以參考一下連結:

http://aisuda.bce.baidu.com/amis/zh-CN/docs/types/api

{
"status":0,
"msg":"",
"data":{
...其他欄位
}
}

而正如前文所說,低程式碼平臺很多時候需要去連線舊的線上介面,這些介面返回的資料格式往往不符合低程式碼平臺的要求,並不太可能 “為了適配低程式碼平臺” 而去進行專門改造。

那麼除了為低程式碼平臺定製開發一套專用介面外,有沒有辦法能夠既享受低程式碼平臺帶來的便利,又能減免後端介面的改造成本呢?

這個問題我們將在本篇的第 5 到第 7 節做統一解答。我們先來看一看另一個前端經典問題 —— 跨域問題的產生。

    4.2 跨域問題

如前文的圖 2 所示,當前線上業務的域名是 a.xxx.com ,而低程式碼平臺的域名是 b.xxx.com,這意味著舊的線上介面可能無法被來自 a.xxx.com 的前端請求直接訪問,而如果要求後端改造現有介面或伺服器配置來多相容一個域名,也可能導致不可控的成本和安全隱患。

“跨域問題” 的實際效果如圖 3(圖片來自百度搜索),前端開發人員都非常熟悉的 blocked by CORS policy 報錯。

圖 3  前端向不同域名傳送的請求由於跨域被瀏覽器攔截

為此,低程式碼平臺愛速搭提供了“瀏覽器端的資料對映機制”、“瀏覽器端請求/接收介面卡”和“ API 代理”等幾項能力來協作解決第 4 節提到的這兩個問題。

藉助這些能力,可以在後端介面不做任何改動的情況下實現低程式碼平臺對業務的平滑接入。

5. 瀏覽器端的資料對映機制

資料對映,指的是在介面傳送 / 接收前將原始欄位的值賦給目標欄位,例如後端返回的格式是 {a: 'xxx', b: 'ooo'} 而前端元件需要的格式是  {c: 'xxx', b: 'xxx'},在資料對映中配置 c: ${a} 就可以將介面返回的資料格式化成前端需要的格式。

在愛速搭中,資料對映分為瀏覽器端資料對映和服務端資料對映。關於服務端資料對映,我們會在本文的 7.2 節予以說明。

瀏覽器端資料對映在愛速搭中的配置介面如圖 4 所示,可以在面板上開啟 “資料對映” 開關並以 key: value 的格式進行資料對映配置。

圖 4  用資料對映解決資料格式匹配問題

需要注意的是這個 “對映” 是在資料介面請求傳送之前 / 返回之後在瀏覽器端進行的格式化,所以設定之後觀察介面返回資料也不會看到任何改變。

該能力是在 AMIS 框架中實現的,愛速搭對其進行了視覺化封裝,關於 AMIS 框架中的實現,可以閱讀官方文件:

http://aisuda.bce.baidu.com/amis/zh-CN/docs/concepts/data-mapping

6. 瀏覽器端請求 / 接收介面卡

在簡單的對映無法滿足複雜的資料格式化需求時,愛速搭還提供了通過 js 函式來對資料格式進行處理的方式。

如圖 5,可以在 CRUD 元件的 API 配置處編寫 js 函式程式碼,在請求傳送 / 請求結果返回時,這些自定義函式會被呼叫來對資料進行格式化,這個 “格式化” 的過程也是在瀏覽器端執行的。

圖 5  在愛速搭平臺 中編寫介面卡函式

該能力同樣是在 AMIS 框架中實現的,具體見 AMIS 文件:

http://aisuda.bce.baidu.com/amis/zh-CN/docs/types/api#%E9%85%8D%E7%BD%AE%E8%AF%B7%E6%B1%82%E9%80%82%E9%85%8D%E5%99%A8

7. API 代理

跨域問題產生的根本原因是瀏覽器對跨域訪問的限制 。在低程式碼平臺實際落地的場景中,低程式碼平臺和業務往往部署在不同的域名下,並且業務方也通常不可能為了接入低程式碼平臺而增加額外的跨域訪問白名單或獨立部署一套同域下的低程式碼平臺。故而 “跨域問題” 也是低程式碼平臺落地的一大阻礙。

    7.1 統一 API 代理方案

處理跨域問題的方案有很多種,愛速搭採用了統一 API 代理的方案,通過後端的代理服務來對 API 請求進行統一轉發,從而規避了跨域請求被瀏覽器攔截的問題。

下面我們來看一看愛速搭中 API 代理服務的具體實現。

在愛速搭中,預設情況下元件中填寫的介面配置在不是由前端直接向服務端發起請求,而是經由愛速搭的 API 代理服務進行轉發後再將實際後端介面返回的資料通過代理服務返回到前端。

如圖 6,在 Form 元件上配置了一個儲存介面的 url。

圖 6  Form 元件上配置的儲存介面 url

實際發起請求時訪問的 url 如圖 7:

圖 7  實際發起請求時通過 Proxy 介面

從原理上說,愛速搭 API 代理的執行方式是在編輯儲存階段將頁面中的 API 抽出來存到一個數據庫表中,並給每個 API 生成一個標識,然後在執行時實際訪問的是類似  api/proxy/:apiId 這樣的介面,再由後端服務通過 apiId 找到實際的介面 url,轉發請求並等待遠端返回後再將結果返給前端。API 代理在當前市面上的低程式碼平臺中是一個 “標配” 服務。

跨域問題只存在於前端瀏覽器層面,這種通過後端介面轉發請求的方式,從根本上規避了前端跨域問題的產生

    7.2 後端資料對映及後端請求 / 接收介面卡

除了簡單的轉發,愛速搭的 API 代理還提供了後端執行的資料對映和介面卡等機制。在應用設定 - 介面 - 全域性介面介面卡中可以為 API 代理配置全域性介面卡,如圖 8 所示:

圖 8  全域性介面卡

而在愛速搭中如果希望為單個 API 配置對映和介面卡,可以 API 中心新建單個介面並填寫相應配置項,如圖9所示:

圖 9  為單個介面配置設定引數轉換和介面卡

為什麼有了服務端執行的資料對映和請求 / 接收介面卡,還需要前面所說的瀏覽器端執行方案呢?

原因有兩點:

  • AMIS 作為一個開源專案,在許多時候可能會被作為獨立依賴引入到專案中,在沒有 API 代理機制的情況下前端方案可以解決一部分問題。

  • 如果在配置項中指定請求為 raw: 則網路請求不會經過 API 代理髮送,這時如果需要對資料進行格式化,則需要藉助前端方案。

此外,愛速搭還開放了自定義 header 等請求資訊的配置能力,由於篇幅所限,本文不再一一贅述,有興趣的讀者可自行查閱愛速搭或 AMIS 官方文件。

8. 小結

通過上述幾個方案,愛速搭解決了低程式碼平臺在實際落地時的改造成本和溝通成本問題,使得業務不再需要為了享受低程式碼平臺的便利而進行可能帶來更多麻煩的改造工作。

但基於單 API 通訊的方案仍然依賴於 “現成” 的介面。如果是全新的功能,依舊需要由後端開發人員以傳統模式進行 API 的開發和部署上線 —— 當然,並不能武斷地認為這種方案就應當被淘汰,因為在實際生產環境中,許多通用型的介面已經作為穩定的數字資產被沉澱下來,作為open api 提供給業務方使用,以 API 方式來呼叫這些通用介面,顯然最合適不過。

那麼在後端介面也 “不存在” 的情況下,有沒有辦法能夠通過低程式碼平臺快速開發上線應用呢?答案是肯定的。為此愛速搭平臺提供了 API 編排,FaaS 和資料庫直連方案,我們將在本文的(下)篇中介紹這些新型的技術方案。

  往期推薦  

:link:

視覺化神器背後的奧祕

6000字,詳解資料倉庫明星產品背後的技術奧祕

“智感超清”之HDR技術落地實踐