[Work] 前後端分工的觀察
前言
學生時期做過前後端協作的專案,但因缺乏討論,後端寫 API 時前端還在切元件,因此等到要串接時,只能對後端寫的回傳格式照單全收,又或者修修改改,要後端配合前端渲染方便所需的格式而組出奇怪的資料結構,並沒有一個討論出一個格式或職責分工的標準。後端工程師工作至今快半年,透過實際解決客戶需求、和前端工程師合作開發,以及接受技術主管的任務分派,也體驗到實務上的情境、對應的做法確實與學生時期大大不同,以此篇紀錄這陣子協作的心得與疑問。
這個主題會分兩篇,一篇是我在工作上的觀察與疑問,另一篇收集網路上的說法,看看大家對前後端分工、商業邏輯的配置是如何分別。
情境
由於公司產品(ioT)近期正經歷調整的階段,慢慢轉為多個微服務的架構,因此我也獲得自己 own 一個 service 的學習機會,在從零打造 service API 到與前端工程師協作、到 review 產品功能定義到與 UI/UX 設計師討論的過程中,也經歷了不少「協調」與「配合」。
這次的 service 其中有一支 API 為歷史線圖的呈現(以上圖為例),前端必須向後端要求資料,透過 chart library 來呈現。而因為內部 DB (MySQL/MariaDB)並不會儲存產線機台「停機時間」內的資料,造成資料不連續,若直接將這樣的資料撈出吐回去給前端的話,對於使用者而言,將會很難看出「停機時間的變化」且不直覺。因此,由於前端使用的 chart library 的限制,我們需要對撈出來的資料做處理,補上缺的 timestamp 與 null 值來製造圖表上的斷層(沒有 bar 的時間戳)。
問題1:前端補?還是後端補?
由於我負責的功能是分析與觀測頁面,有多支 API 都需要這樣的線圖資料,因此站在維護的角度,勢必要討論出一個統一的做法,並套用到全部 API 上。
但…
「如果在前端補的話太吃效能,使用者體驗不好」
「但後端應該要忠實回覆來自 DB 的資料,在後端對資料做太多加工真的好嗎?」
「這是為了前端 library 的格式而補,因此它和 UI 相關,應該要前端補才對?」
「前端要補的話還需要時間等參數,還需要後端再回一次,太麻煩
「有多支 API 需要這樣的邏輯,那是否寫在後端共用更好?」
@#$%^!!&%^*@#$#$…
問題2:後端來的資料應該是原汁原味,還是可為了前端呈現進行資料再加工?
目前有幾個線圖所需呈現的資料都是需要經過「再加工」的。例如將不同機台收集的數據「根據分類,進行加總、平均等等」,而這些計算的目的都是為了「前端 UI 的呈現」,那麼是否應該在前端做處理呢?
我認為所謂後端原汁原味的資料,可以接受加工最大的幅度應該是:在 DB 下 query 時,取某區段時間內值之 avg,或取得某區間的 max - min 等等,這樣原始、「包含商業邏輯但不包含 UI 考量」的數據。
另一個例子是,過去在撈取資料回覆前端時,若超過一個月的資料量,會因為筆數龐大(DB 目前是每 10 秒一筆)而造成效能不佳。後來做了 down sampling ,制定好不同的時間區間所需的抽樣筆數,並將時間戳取至整數點,例如分、小時、天、月等,大幅改善效能(撈一個月 20 秒 → 一秒多)。這種的我想也算是原汁原味,畢竟只是因為抽樣的關係,呈現的筆數較少,沒有對原始資料做「加工」,依然忠實呈現 raw data。
問題3:前後端格式與易維護性?
由於前端 code base 並無拆分 service,大部分元件仍沿用前人的寫法,因此就算架構並不彈性、格式雜亂,在有限的時間下難以進行重構,仍需沿用前人的架構來撰寫。剛好後端拆分 micro-service 帶來了重構的契機,可以在 API 回傳值中做出架構更乾淨、更好維護的資料格式,此時與前端元件原本定義需要的資料格式便有了衝突。
在產品、code base 迭代的過程中,究竟要使用「方便前端渲染」的格式,還是「方便後端擴充維護」、「盡量呈現 DB 原始資料格式」的格式呢?
釐清需求與職責
最後我們決定的方式是依照前後端的「需求」,來評估資料的處理、格式的整理,究竟該如何分工。
以歷史線圖的功能為例,在前端,使用者想看到的資料是一個主節點下,分別子節點下電表的加總 (UI 考量)。
而後端 DB 是以一個電表一個 table 為單位來儲存資料,因此這時候就必須先撈出所有電表資料 (raw data),再根據子節點、主節點的關係 (商業邏輯),加總後進行分類 (商業邏輯),回覆給前端。
因此,我們得出的結論:
UI 考量(使用者想看的東西) —> 前端來做
這邊指的是「組合出前端 library 所需的格式」、或是為了「呈現某種使用者想看到的資訊而做的邏輯」,例如:由後端收集了每個子節點的資訊,而使用者會想看到主節點下所有子節點的總和,因此「加總」這件事,我認為應該由前端來做,後端只負責將子節點的資料傳到前端而已。
商業邏輯(產品提供的東西) —> 後端來做
以「每小時消耗電量」為例,需要將每小時內最後一筆資料 - 第一筆資料,得出每個小時總消耗電量。這部分甚至可以在 DB 端完成,我認為只要這份資料最後的模樣來自於該 table 內的「簡單計算」(加減乘除、平均、找最大最小值… 等),都能算是 raw data,因此後端做到這裡為止,我認為都算合理。
大家都怎麼做?
前後端如何分工並沒有標準答案,或許不同團隊有不同的作法,每個團隊對於 MVC 架構的認知與考量不同、每個工程師熟悉的分工模式也不一樣,不能一言以蔽之。因此,只要透過與前端工程師的來回討論與磨合,互相妥協約定能夠加速開發、好維護的格式,都是合理的作法。(曾經有個老鳥告訴我,只要能動都好… 咦?)
雖然現有的合作模式還算好辦,我仍十分好奇在其他地方,前後端工程師都是怎麼協調合作、根據什麼樣的考量去分工、或是為了追求易維護性而選擇什麼樣的責任分派方式?這也帶出了一個困擾我很久的問題: 商業邏輯應該放在前端還是後端?
為此我查了一些資料,歸納出幾個不同的派別。下一篇,就來看看網路上其他開發者怎麼說~