架构设计系列-前端模式的后端(BFF)翻译PhilCalçado
本文翻譯自PhilCal?ado的官網(wǎng):https://philcalcado.com/2015/09/18/the_back_end_for_front_end_pattern_bff.html
對我們的架構(gòu)演變保持透明是我們技術(shù)戰(zhàn)略的一部分。我們在無數(shù)場合談過的但從未真正詳細描述過的東西是我們應用后端用于前端架構(gòu)模式或BFF。這篇文章記錄了我對如何開發(fā)和應用這種技術(shù)的理解。
我對軟件組件演變的理解
在完全分布式架構(gòu)變得可行之前,組織通常會在一個或多個層中構(gòu)建應用程序。層是應用程序的高度耦合但相當獨立的組件。據(jù)加上在這,而不是服務,它被認為僅由一個應用程序使用的感覺。它獨立于如何不作為同一過程的一部分運行,甚至通常不在同一臺機器中運行。
讓我們用三個虛構(gòu)的應用來說明這一點,當時任何大公司都會發(fā)展出來:
這些體系結(jié)構(gòu)可能變得非常復雜,但總體而言,在不同的應用程序之間繪制線條非常容易,清楚地劃分出一個開始和另一個結(jié)束的位置。
當時,每個應用程序都有自己的數(shù)據(jù)副本和重復的常見業(yè)務流程實現(xiàn)。隨著時間的推移,隨著組織獲得或構(gòu)建越來越多的應用程序,我們意識到我們需要不同的東西。我們需要應用程序來共享數(shù)據(jù)和重用邏輯,而我們曾經(jīng)簡單的架構(gòu)變得有點復雜:
隨著對更多重用和整合的需求,軟件行業(yè)的集體思維方式?jīng)Q定了一個非常抽象的概念,稱為服務。實際上,這意味著上面的圖表改為類似于此的東西:
上述架構(gòu)的賣點是這些可重用服務提供的靈活性。理論上,在這個平臺上構(gòu)建應用程序現(xiàn)在是一個問題:
與此同時,計算機和互聯(lián)網(wǎng)正變得越來越流行。過去與職員或系統(tǒng)操作員交互的客戶開始直接與應用程序本身交互。設(shè)計思維和用戶體驗研究使我們擺脫了復雜的用戶界面,專注于讓專家用戶更高效地獲得更豐富,更實用的體驗,客戶可以理解這些體驗 - 沒有人閱讀網(wǎng)站手冊。更豐富的經(jīng)驗需要豐富的數(shù)據(jù),這意味著匯總來自各種來源的信息。
按照我們的示例,我們最終會得到如下圖所示的內(nèi)容。
我們不再擁有業(yè)務線系統(tǒng)的用戶界面,而是越來越多的用戶界面本身就是應用程序。這些應用程序通常用JSP,PHP或ASP編寫,其代碼包含用戶界面和特定于應用程序的后端邏輯。
打破巨石
上面簡單的例子與許多現(xiàn)代技術(shù)組織的架構(gòu)發(fā)展方式?jīng)]有什么不同。2011年,SoundCloud的網(wǎng)站如下所示:
Logic和All邏輯在一個地方。有一個系統(tǒng),而這個系統(tǒng)是該應用程序。
如前一篇文章所述,我們發(fā)現(xiàn)此架構(gòu)存在許多問題,并決定將邏輯提取到微服務中。盡管我們在提取后端服務方面取得了成功,但最長時間內(nèi)母艦仍然處于每個請求的關(guān)鍵路徑上。
我們正在進行的架構(gòu)改變背后的主要動機是縮短新功能的上市時間,我們發(fā)現(xiàn)我們最糟糕的瓶頸在于任何必須觸及整體的變化。考慮到用戶界面更改的頻率,從整體中提取代碼是一種提高生產(chǎn)力的直觀方法。然后,我們在其自己的組件中提取了我們的UI層,并使其從我們的公共API中獲取數(shù)據(jù):
早在2011年,當這些架構(gòu)發(fā)生變化時,絕大多數(shù)用戶都在網(wǎng)上。正如Fred Wilson所預測的那樣,最終這種情況發(fā)生了變化,我們的用戶群開始使用移動應用程序的方式比Web界面更頻繁。SoundCloud已經(jīng)為Android和iOS提供了很長時間的移動客戶端,與我們的新Web應用程序類似,他們直接與我們的公共API進行了對話。
dogfooding帶來的挑戰(zhàn)
在現(xiàn)代軟件工程中,狗食通常被認為是一件好事。在我們自己的API之上構(gòu)建我們的產(chǎn)品被認為是確保我們的API具有高質(zhì)量并且始終是最新的最佳方式。在實踐中,我們遇到了這種方法的幾個問題。
我們的第一個問題不一定與技術(shù)有關(guān),而是產(chǎn)品開發(fā)的根本挑戰(zhàn)。如果我們僅使用公共API,那么我們的平臺中沒有任何內(nèi)容可供第三方API客戶端使用。盡管我們想要一個蓬勃發(fā)展的SoundCloud集成生態(tài)系統(tǒng),但我們還是一家廣告公司,因此我們需要確保人們使用我們的屬性,而不僅僅是我們的數(shù)據(jù)。創(chuàng)建我們自己的應用程序獨有的功能意味著我們必須在許多地方不斷檢查OAuth范圍,并使人們很難欺騙我們的“官方應用程序”密鑰。
在一個更技術(shù)性的問題上,我們的公共API幾乎按照定義是非常通用的。為了使第三方開發(fā)人員能夠構(gòu)建有趣的集成,您需要設(shè)計一個不會假設(shè)數(shù)據(jù)將如何使用的API。這會產(chǎn)生非常細粒度的端點,然后需要對多個不同端點的大量HTTP請求才能呈現(xiàn)最簡單的體驗。您可以在下面看到我們過去在整體時代提出的請求數(shù)量與我們?yōu)樾碌腤eb應用程序生成的請求數(shù)量:
要生成該單個配置文件頁面,我們必須對不同的API端點進行多次調(diào)用,例如:
- GET /tracks/1234.json?(該曲目的作者)
- GET /tracks/1234/related.json?(推薦相關(guān)的曲目)
- GET /users/86762.json?(關(guān)于該曲目的作者的信息)
- GET /users/me.json?(有關(guān)當前用戶的信息)
- ...
...然后,Web應用程序?qū)⒑喜⒁詣?chuàng)建用戶配置文件頁面。雖然這個問題存在于所有平臺上,但對于我們不斷增長的移動用戶群來說,情況更糟,因為他們經(jīng)常使用不可靠且速度慢的無線網(wǎng)絡(luò)
我們在上面的體系結(jié)構(gòu)中遇到的第三個甚至更煩人的問題是,即使沒有整體結(jié)構(gòu),我們?nèi)匀淮嬖贏PI的瓶頸。每當團隊需要更改現(xiàn)有端點時,我們都需要確保更改不會破壞任何現(xiàn)有客戶端(包括重要的第三方集成)。每當我們添加新內(nèi)容時,我們都需要投入大量時間來確保新端點不會過度專用于特定應用,所有客戶都可以輕松使用它們。所有這些協(xié)調(diào)使我們的日常工作變得比應有的困難,并使我們幾乎不可能進行A / B測試并減慢新功能的推出。
前端模式的后端(BFF)
在上述架構(gòu)首次亮相近一年后,我們開始準備開發(fā)新的iOS應用程序。這是一個龐大的項目,最終會改變所有房產(chǎn)的用戶體驗。如此高風險,開發(fā)過程中的實驗和迭代至關(guān)重要。當工程團隊開始考慮應用程序的體系結(jié)構(gòu)時,我們發(fā)現(xiàn)上述挑戰(zhàn)將成為項目的阻礙,我們需要重新思考我們的工作方式。
我們首先提出的解決方案是為移動和網(wǎng)絡(luò)提供不同的API。我們的想法是,讓客戶擁有API的團隊可以讓他們更快地移動,因為它不需要部件之間的協(xié)調(diào)。我們最初的想法是為不同的前端設(shè)置不同的后端。BFF一詞是由我們的網(wǎng)絡(luò)技術(shù)主管Nick Fisher創(chuàng)造的(我最初的建議是BEFFE,但我們講荷蘭語的隊友否決了這個選項)。
在它的第一個版本中,這些后端看起來仍然看起來像公共API,許多通用端點需要來自客戶端的許多調(diào)用來呈現(xiàn)單個屏幕。但是,隨著時間的推移,我們發(fā)現(xiàn)了一些有趣的事情。以用戶配置文件頁面為例,以前這是一個僅存在于客戶端的概念。Web或移動應用程序?qū)母鱾€端點獲取數(shù)據(jù),并使用它來創(chuàng)建我們稱為用戶配置文件的對象。這是一個特定于應用程序的對象。
在某些時候,我們的客戶團隊意識到,由于他們擁有API,他們可以將這個對象推向API。他們可以提取所有調(diào)用不同服務的邏輯,并將它們一起混合到后端的用戶配置文件中。
這最終將簡化代碼并提高性能。不是對上面描述的多個端點進行多個不同的調(diào)用,而是需要請求的所有客戶端都是單個資源:
- GET /user-profile/123.json
當我們進一步嘗試這個模型時,我們發(fā)現(xiàn)自己在BFF中編寫了很多演示模型。在這個階段,我們意識到BFF不是應用程序使用的API?。BFF是申請的一部分。
最終,我們的所有屬性(包括API)都開始遵循此模式。
一直往下
在某些時候,我們生產(chǎn)了大約五種不同的BFF,我們已經(jīng)開始研究如何進一步提高生產(chǎn)率。接下來是我們的用戶配置文件示例,對我們來說顯而易見的是,鑒于每個應用程序都有一個等效的用戶配置文件頁面,所有BFF都有很多重復的代碼來獲取和合并它們的數(shù)據(jù)。
復制并不準確,像網(wǎng)絡(luò)瀏覽器這樣的大屏幕在其用戶個人資料頁面上的信息要比微型移動應用程序多得多。然而,我們看到重復是一種難聞的氣味,表明我們在域模型中缺少一個對象。為了解決這個問題,我們創(chuàng)建了一個UserProfileService處理這個重復邏輯的方法。
隨著時間的推移,我們發(fā)現(xiàn)了越來越多這樣的情況。我們開始有意識地轉(zhuǎn)向一個架構(gòu),在這個架構(gòu)中,用戶理解的大多數(shù)核心對象都有自己的微服務支持它們。
轉(zhuǎn)載于:https://www.cnblogs.com/BlogNetSpace/p/4866748.html
總結(jié)
以上是生活随笔為你收集整理的架构设计系列-前端模式的后端(BFF)翻译PhilCalçado的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx 使用中文URL,中文目录路径
- 下一篇: Nginx的安装和配置文件详细说明