系統設計面試心得 從 Slack 分享 API 的設計心法談起

me
林彥成
2022-01-06 | 3 min.
文章目錄
  1. 1. 系統設計面試
  2. 2. API 設計方法
    1. 2.1. 一次做好一件事
    2. 2.2. 容易且能快速維護
    3. 2.3. 一致性
    4. 2.4. 回傳有意義的錯誤訊息
    5. 2.5. 考量效能和可擴充性
    6. 2.6. 避免 breaking changes

系統設計面試

經過兩次體驗及提醒,終於知道系統設計面試的流程和進行方式。

  • 對象: 通常會針對比較資深的工程師來進行
  • 進行方式: 會像是實際上工作的討論
  • 目的: 了解過去遇過的問題以及處理經驗

前陣子第一次體驗的時候,完全搞不清楚對方想要問什麼,只覺得給了一個大範圍的問題,是要我直接講公司內部的秘密嗎? 當時也沒有反問對方想問什麼且對方也沒有引導,所以整場系統設計面試感覺就很奇怪。

第二場有了前次經驗,這次就直接問對方想要問什麼或需要我表達什麼,經過引導之後就比較了解狀況,覺得可以不用當作面試,就當作在工作討論未知問題即可,對於平常比較少畫架構圖的工程師可能會比較不習慣。

在跟面試官互動的過程中會需要

  1. 先確認功能以及相關條件,剛開始都沒有給太多限制
  2. 決定可能會用到的元件在白板上畫架構圖
  3. 針對架構圖做簡單的說明
  4. 資料傳遞的格式

通常都會以一個範圍比較大且有想像空間的題目開始,但通常會先限縮範圍

  • 如果要設計比特幣的報價跟交易量呈現,你會怎麼設計
  • 臉書的個人發佈動態跟顯示,顯示追蹤的朋友動態

在畫架構圖的過程中,通常也會被問問題

  • 你要用什麼 DB 為什麼決定用這個?
  • RDB 跟 NoSQL 差別在哪
  • 表要怎麼開,欄位怎麼關聯,資料打算怎麼放

在畫了相關元件跟架構圖後,會開始延伸可能的條件或是想要實作的功能

  • 及時交易量要怎麼做到
  • 怎麼決定要顯示哪些朋友的動態,你的資料庫會怎麼決定
  • 如果今天要加入按讚或是推文訊息的更新要怎麼做

接下來的六個概念主要翻譯 Slack 團隊分享的 how we design our apis at slack

API 設計方法

以 API 的設計來說,主要會包含但不限於底下六個原則:

  • 一次做好一件事
  • 容易且能快速維護
  • 一致性
  • 回傳有意義的錯誤訊息
  • 考量效能和可擴充性
  • 避免 breaking changes

在 API 系統設計流程上粗分則有三個階段:

  1. 規格文件
  • 定義開發相關需要內容
    • method 名稱
    • 用途
    • request 範例
    • response 範例
    • 相關錯誤訊息
  • 可參考 OpenAPI、AsyncAPI
  1. 內部 Review
  • changes: 這次修改了什麼,會不會影響其他已經上線的 API? 有 follow semantic-release 的話這方面不用擔心
  • guidelines: 是否有依照團隊、文件上規範去設計,團隊寫出來的能夠如出一轍最棒了
    • 命名
    • 可用性
    • 安全性
    • 效能
  1. 早期使用者回饋與 Beta 測試

舉 Facebook 維護的 React.js 來說就會提供像是 unstable_createRoot 這樣的 API 讓早期使用者去使用並回饋。

1
2
3
4
5
6
7
8
9
import ReactDOM from "react-dom";

// If you previously had:
//
// ReactDOM.render(<App />, document.getElementById('root'));
//
// You can opt into Concurrent Mode by writing:

ReactDOM.unstable_createRoot(document.getElementById("root")).render(<App />);

一次做好一件事

在 Function、API、元件、hook 的設計上,一次做好一件事都是重要的觀念,原因主要是:

  • 專業分工,也更容易優化效能
  • 加東西比拿掉容易
  • 容易理解
  • 容易擴充
  • 更安全

容易且能快速維護

這同時也是使用框架或是架構良好的專案的優點,在畢業時我第一份工作就是後端工程師負責開 API,當時維護的專案是以 Java Jersey 為基礎的專案,現在回頭看就是一個架構良好、切分乾淨、容易且能快速維護的專案。

  • 良好的 Quick Start Guide
  • 使用說明清楚
  • 有示範的程式碼
  • 文件可以直接互動,若沒有也可以使用 Postman 共用帳號來達到

一致性

在第一份工作的時候,就曾被主管要求過這件事情,他會希望同樣一個專案,不同的人寫出來的要像是同個人的作品。

  • 符合業界標準
  • 不同專案也是要有一致的命名規則
  • 寫作上的邏輯一致
  • 命名避免縮寫、行話
    • FYI
    • idx -> index
    • fname -> firstName


圖片來源: https://slack.engineering/how-we-design-our-apis-at-slack/

回傳有意義的錯誤訊息

語意化這件事情在註解、變數或函式命名、錯誤訊息都非常重要,也能說是常見的一種溝通技巧。


圖片來源: https://slack.engineering/how-we-design-our-apis-at-slack/

考量效能和可擴充性

以臉書的貼文留言來說,就需要透過分頁來加速載入的速度,再來就是減少巢狀的資料格式來降低複雜度

  • 分頁: 對後端來說一次撈取大量資料容易造成資料庫的瓶頸,對前端來說也會造成操作上的卡頓
  • 減少巢狀資料格式: 兩個大資料及巢狀合併會大大提升複雜度
    • channels.list: list of channels and all members in each channel
    • conversations.list + conversations.members
  • 限制速率: 當 API 會被特定使用者或是爬蟲固定爬取時,就建議可以設定一些限制

避免 breaking changes

通常版本升級理論上都要可以向下相容,才不會造成新版本上線後舊版程式無法使用的狀況。

過往待過公司經驗會是直接透過 URL 路徑來做區分:

  • /v1.0/getUserInfomation
  • /v2.0/getUserInfomation

若是有需要汰換 v1.0 也建議在 response message 中明確的留下提示。


喜歡這篇文章,請幫忙拍拍手喔 🤣

share