Contents ...
udn網路城邦
如何將MVC網站API化
2022/09/16 19:28
瀏覽418
迴響0
推薦2
引用0

本文是寫給Web仔看的,非Web仔看不懂正常也不建議閱讀。


目前主流的Web開發有兩種。


一種是走MVC框架,擁抱Ruby on Rails的慣例優於設定的一套快速Web開發模式。

這種模式可以快速應用框架把網站開發出來,通常有一整包常用工具組合,整個套餐都使用,第一個網站可能一個下午就搞出來了。

同樣也有模組化與外掛擴充的空間,不過就是一個請求回傳一個頁面,如果那個頁面需要提供不跳網址的互動功能,回傳的網頁就需要連這些互動的前端Javascript一起回傳提供。

簡單說,就是常見的需求可以很快完成,也有很多規範與提升品質的機制,但需求較複雜較細緻時會變得比較難開發維護就是了。

基本上大部分熱門的程式語言都有向RoR致敬的框架,如PHP的Laravel或Python的django,或者說大部分以MVC設計模式為核心的框架都是這個風格。


另一種則是微服務的前後端分離的API化設計。

這種模式是追求靈活,讓系統的本質是由API服務的組合構成,然後可以串接別人也可以被人串接,系統核心就是後面的API與數據流狀態的維護。

這樣是增加一些靈活度,也方便同時給多種前端如PC與兩種手機App串接,不僅是Web使用而已。

不過呢,API是不太可以給一般使用者直接操作的,所以通常會搭配前端框架來串接API。

用這種模式開發的網站,就會做到Web2.0剛推出時說的,完全不需要多餘的頁面重整,可以每個動作只呼叫對應的API,然後只做必要的畫面更新。

從另一個角度來說,如果前端開發串接API的部分搞不定,只有API看不到使用者介面等於沒完成任何東西那樣。


如果要從第一種的模式往第二種轉型,後端的技術上難度不高。

只要把原本抓樣板處理view的那一段,改成controller最後return直接如response()->json(['status' => 0])這樣那就是api了,更簡化而已。


簡單嗎?

如果看網路上查到的範例,其實,也不怎麼簡單。

因為通常API設計都會有Restful風格或Graphql風格的設計方式的爭議。

而實際上,不管兩種選哪一種,都很難搞。

Restful風格會把網址路徑和資源做對應,認為所有的API都應該是針對資源的簡單CRUD的基本操作,然後應該要配合Web標準,C用Post然後R用Get而U是Put最後D是Delete。

還會說應該要回應正確的http的狀態碼,沒有照規範就會被罵那樣。

所以通常設計API都會被這種哲學教條綁架,不然就是你技術Low啊。

於是只好把所有數據結構的CRUD都暴露出來,避免被鄙視啊。

於是,根據商業需求使用者流程的一個動作需要的數據如果複雜了一點,可能就是需要呼叫很多次那個Restful風格的API,效能差不說還很蠢。

因為這種蠢,所以又冒出一個新的技術標準,新的API設計模式,就是那個Graphql。

Graphql解決了複雜資料結構需要前端多次呼叫存取的問題。

但這個作法本身就是個新問題,數據結構的定義與曝露規則變得更複雜了。

如果需求變動頻繁,數據結構變動也很頻繁,那搞Graphql的工程師可能會想罵娘吧。

簡單說就是全面提升前後端串接API的學習曲線那樣。

就這麼看,把資訊系統API化,貌似也不是多有生產力與效率的做法吧?


其實呢,別管他那個Restful風格的API規範,也別管那個Graphql的技術規範,設計API直接就照那老掉牙的程序導向程式設計,把API當function設計就好了。

每一個API都有標準的請求介面,包含請求網址路徑,請求表頭與請求內容這三塊。

無論如何,後端的API一定是根據請求內容的輸入來決定應該回傳什麼內容回去。

所以呢,我們認為這個功能就是由某幾個數據操作的動作構成的,如一進來先抓取列表資料,設定篩選條件後可以重新查詢顯示篩選後的資料,點擊列表的資料需要把明細資料用表單完整呈現,點修改需要可以修改帶出來的資料後送出存檔,也要可以列表按刪除經提示再確認後刪除資料,喔,那就每個動作都提供一個API就好了。

如果列表回傳詳細完整的資料,那麼前端就可以先保存起來,當被點擊查看明細或想點擊編輯修改時可以直接帶出來不需要再查詢一次。

如果列表回傳數量較多,每一筆資料的明細資料內容又比較龐大,或數據檢視與更新即時性比較重要,則會設計成列表的API只回傳列表需要的數據就好,需要某一筆完整資料時再呼叫另一個API去取得那一筆的完整數據。

列表需要的欄位一個數據表不能滿足時,只要在那個列表的API實現內部設法看是SQL Join還是ORM低效多loop幾次,總之根據請求的需要把數據都取得整理後再回傳就是了。

需要什麼就那麼處理並回傳,有需要去搞一套把所有數據結構開放給前端,讓前端可以再最大彈性下自行下條件撈出他要的資料嗎?

完全沒必要這樣。

甚至可以在每一個API的執行時,根據實際業務邏輯的需求,各自寫檢查規則,根據實際的情況給予合適的回應就好,如訂單建立前檢查庫存與檢查活動套用折扣條件是否正確等等。

在沒有Web服務之前,那些Rpc的遠端呼叫不就是這樣設計的嗎?

就像玩網路遊戲,數據一定是以服務器遠端的為準,前端的操作都是為了影響遊戲世界,也就必須透過API去和遠端互動,API當然可以這樣理解啊。

所以那些API風格與規範多只是那些Web框架生態系統產生出來的設計哲學,在某些情境下有其意義,例如你的API只是要做Open Data而已,那介面盡量保持簡單,就會比較好懂好維護不會亂成一團。

而當想要設計貼心高效的使用者體驗的使用者互動介面的時候,或者說豐富的互動體驗的時候,那些風格規範就是屁了。


所以呢?

API設計本來就不用照數據結構去定義,我們完全可以依照User Story的各個動作去定義每一個需要的API。

每個API就做我們需要的,它該做的事就好。

甚至API也不一定要和請求網址路徑去一一對應,只要呼叫的參數裡面提供足夠資訊,把要做甚麼的指令放放QueryString或放post body都可以的。

其實那些設計哲學不應該刻板的死抱著,滿足實際的需求比較要緊。

例如同樣是微服務,也會有一些不同的派系與堅持,如堅持每個微服務都應該有自己的獨立數據庫,與其他微服務應該透過API換,最小單位服務模組該怎麼切等等。

該考慮的只有成本效益,怎樣適合就怎麼做,有問題再檢討改善就是了。


所以結論是,如果要讓MVC的網站架構轉型到微服務的API為核心的模式,只需要拉一組API用的Controller,回傳結果時回傳json,以及不要綁死Restful設計風格,就想像自己從MVC改成MVP設計模式,Controller可以改掉用另外加一個Service層,該層再去調用原本就可以用的Model,這樣應該是改動較少又能收穫靈活彈性的調整方式了。

很常見的架構實務是底層有ORM的MVC,但實際上把MVC改成MVP不拘泥於Restful風格,M的概念部分由Service取代,且在效能比較關鍵的地方會捨ORM而用可以下SQL的工具操作數據庫。

現在讓系統API化是大趨勢,但萬變不離其宗,軟體工程核心還是複雜度的治理,不要為了API而API,要轉型前先想想實際的需求吧!

有誰推薦more
全站分類:不分類 不分類
自訂分類:吐口水
下一則: 通貨膨脹與升息的邏輯問題
發表迴響

會員登入