1 of 64

DevOps 潮流下的 API First 開發策略

91APP 首席架構師,

Andrew Wu, 2022/10/07

2 of 64

Andrew Wu

  • 現任 91APP, 首席架構師 Chief Architect
  • 榮獲 Microsoft MVP 微軟最有價值專家 獎項,2016 ~ 2023
  • 擔任多次 Microsoft Azure Cafe, TechDays, TechEd, �DevOpsDays Taiwan, .NET Conf 等大型研討會講者,與�相關 Azure PaaS 雲端系列課程與企業內訓講師

演講經歷

3 of 64

4 of 64

Agenda

  1. 你的團隊有多 "期待" 推行 API First ?�// 要踩過的坑很多,你有多期待,就有多大的動力跨越障礙
  2. API 的治理策略 (略)
  3. API 的開發策略
    1. 開發流程的改變�// 談 API 的規格, 比起 " interface ", 我覺得用 " contract " 更貼切
    2. 設計方式的改變與標準化�// 練習先找出關鍵的 API 結構,排除所有非必要的細節設計。
    3. 從設計階段就考慮安全性�// 安全性的定義有很多,這邊的認定能被刻意利用,用來影響正常運作的任何因素都列入考慮
    4. 思考是否過度設計�// 過與不及都是極端,團隊需要有足夠經驗與視野的人來決定平衡點
  4. 總結

5 of 64

1. 你的團隊有多 "期待" API First ?

// 先弄清楚 API First 是什麼...

// 要踩過的坑很多,你有多期待,就有多大的動力跨越障礙

// 在大型團隊 (200+) 推動 API First 的甘苦談,以及那些書上沒教你的事

6 of 64

什麼是 "API First” ?

API First, 指的是 API 的順位要擺在第一位考量。請問:�

  1. (從產品經理的角度) 你們的服務是先設計 (service) API, 還是先設計 (product) UI ?�

  • (從技術經理的角度) 你們的系統是先能動 (product) 再抽離 (重構) 客戶需要的 API? 還是先訂好規格 (spec first) 後同時開發 APP 跟 API 實做?

  • (從產品發展的角度) 你們的 API 是當作產品來看待 (有商業模式,有經營與發展策略)? 還是是其他產品線的附屬功能 (一個產品線就對應一組 API, 產品的功能永遠比 API 還完整) ?�

// 你們團隊屬於哪一 種? Product First ? API First ? API as Product ?

> 合作夥伴有能力用 API 開發出能取代你的 Application UI 的功能嗎?�> 你的產品是否有背後的核心服務? �> API 是客戶需要再開? 還是第一天就有? �

> 對內,即使是內部用 API,你也會考量 DX 嗎? 還是可以動就好了?�> DX 跟 UX, 哪一個排在前面?��

> 產品的發展路線,跟 API 是對齊的嗎?�> 產品的功能每年都推陳出新,操作介面都不斷優化改善,UX 越來越好... 你的 API 也不斷地在改變嗎?

7 of 64

推動 API First, 期待的是:

1. 從產品的角度來看:

2. 從系統 (公司) 內部使用的 API 來看:

3. 從團隊之間溝通介面來看:

> 先做好 API ( 好的定義: DX, Developer Experience ), 再來做好 Product ( UX, User Experience )

> 意思不是二選一, 而是要你先搞好 DX, 然後再讓 Developer (內外部都是) 可以開心地搞好 UX

> 系統間的通訊方式就是 API 的規格

> 若系統跟組織是對應的話,好的 API 代表組織之間的分工與溝通是順暢的

> 思考: 為何業界趨勢走向微服務? 為何強調每個服務都應該獨立自主? 傳統單體的三層式架構為何不再盛行?

> 我呼叫你的 API,API Spec 是我訂還是你訂?

> 誰訂都好,重要的是訂好之後簽下合約 ( contract )

8 of 64

API-First Approach

An API-first approach to building software products means that your organization treats APIs with importance, as reusable and easily accessible that client applications consume. API-first means designing products around an API from the ground up, rather than building a product and adding an API later.

API-first means that you treat APIs as critical business assets, understanding the value they bring to your organization. You design each of your APIs around a contract written in an API description language like for consistency, reusability, and broad interoperability. Starting with an API contract allows you to better plan the design of your API and get feedback from stakeholders before writing any code.

Many APIs in use today have been around for more than two decades, but only in recent years have companies begun exploring and adopting the concept of API-first.

9 of 64

老闆期待的: 創造 API 經濟

標準化;規模化����

這些服務背後的關鍵 (為何 API 重要? 他是同時滿足 客戶高度客製化期待,與規模化能量產的期待的解方):

API 的背後代表使用 "服務" 或是 "資料" 的標準方式

高度整合 (不同服務在同一個介面、應用、流程) 帶來便利、效率與自動化

異業結盟,帶來新客群 & 新應用

TSMC: [報導] 把代工做到極致,台積電客製化需求有 258 種製程

SaaS: 把服務做到極致,透過 SI 滿足 B2B 的高度客製化 & 服務品質的需求

91APP推餐飲電商」 助餐飲品牌搶攻百億新商機

- 導入服務: 需要有足夠涵蓋率的 API,來完成跨系統整合或是 UI 辦不到的需求

- 加值服務: 因應跨產品線的功能整合,或是特定產業流程的應用。需要背後服務的模組化來達成

- 應用市集: 加值服務規模化版本,允許第三方協力廠商開發加值服務。API 的授權與管理需要強化到位。

10 of 64

產品團隊的難題: 區分 "服務" vs "應用" 的分界

有那些東西應該要被收斂成 API ? API 是服務被發布的方式,你真正該思考的是你要收斂成什麼服務?

有那些東西該被當成客製化有效率的量產交付,而不是通通都加到標準產品內 ?

如何定義 "足夠" 的彈性? 團隊應該要有關鍵的角色,必須充分了解領域的知識與經驗。過度彈性,或是彈性不足對 API 都有長遠的影響。(敏捷團隊: 架構師是唯一一個需要關注長期規劃的角色)

這是產品發展路線的題目,不是技術實做的題目。

你需要看得清楚發展路線,才能拿捏合適的平衡點。

保留足夠的彈性與發揮空間給產品團隊 / 第三方協力廠商。

產品長、技術長、架構師、技術總監等身分都有可能

案例: Low Code / No Code, 真的不需要寫 code 嗎? 實際情況是 Low Code 比一般應用更依賴高品質的 API / 服務當作基礎。人才需求朝向 M 型兩極化的發展

11 of 64

Ref: Role of Architect in Agile Development

Challenges in Agile Development

While every customer today is adopting agile development irrespective of nature, size of the project, the following are the list of challenges that we foresee as an Architect in agile development. Top challenges are,

  1. Visibility, no end to end visibility on long term client road map (technical and domain).
  2. Resistance, for any suggestions and changes to the existing processes, the acceptability is very low or almost nil from the Customer.
  3. Multiple teams working on different features and different parts of the code base result in architecture foundation structure erosion and code overlap across modules.
  4. Lack of focus on Quality of Service (QoS) attributes.
  5. Requirement Volatility, usually requirements are defined from multiple sources, not just by Business Analyst. Therefore, whenever someone expresses a ‘wish’ that needs to be added to the backlog.
  6. Time Crunch, it was always a compromise between technology, NFR and time. Usually, we do not have any control over time. To make the customer happy, we need to complete all the Business requirements within that time. So the only place we can compromise is technology and NFR.
  7. The latest technology adoption, the approach is to prioritize all the 'visible' requirements first, and then get into others. In the process, we miss the opportunities to implement the latest technologies.
  8. Technical debt, technical considerations are getting lower priority in product backlogs compared to business features. This accumulates the technical debts that need rework.

API / 模組化的彈性掌握,對於產品團隊困難的點就是上述這幾項:

1. 需要看清楚長期 end to end 交付的路線規劃

2. 需要面對跨團隊跨功能的需求

3. 需要做好技術債的管理,拿捏需求與技術債的平衡點

12 of 64

工程團隊: 走向這一步,需要克服的難關

// 產品 & 服務的定義 (抱歉,這次不談這個, 不過你要清楚定義服務才能端出好的 API)

1. 大規模的 API / 服務 治理 能力

2. 大量開放 API 你會需要的 API 管理 (尤其是資安相關) 能力

3. 內部團隊需要具備用 API 溝通協作的能力

- 參考: AWS 2002 年發布的 API 授權 備忘錄

- 評估: 內部團隊是否有能力 "設計" 良好的 API ?

- 評估: 內部團隊是否有能力 "維運" 好 API ?

- 評估: 內部團隊是否有能力 "運用" API 解決問題 ? (黑暗面: 你不能再靠共用 DB / 檔案來協作)

- 思考: 如果團隊之間完全沒辦法用 API 溝通,有沒有可能分工的方式就已經不對了? (微服務: 服務邊界)

13 of 64

AWS 的 "API 授權" 備忘錄 (2002 年...)

  1. 從今天起,所有的團隊都要以服務介面連接埠的方式,提供資料�和各種功能。�
  2. 團隊之間必須通過連接埠來通信。�
  3. 不允許任何其他形式的互操作:不允許直接連結,不允許直接讀取�其他團隊的資料,不允許共享儲存空間,不允許任何形式的後門。�唯一許可的通訊方式,就是透過網路呼叫服務。�
  4. 具體的實際技術不做規定,HTTP、Corba、PubSub、自定義協議皆可。�
  5. 所有的服務連接埠,必須從一開始就以可以公開作為設計導向,沒有例外。這就是說,在設計連接埠的時候,就預設這個連接埠可以對外部人員開放,沒有討價還價的餘地。�
  6. 不遵守上面規定者,一律開除。

// 看到這邊,你的團隊還是期待要做到 API First 嗎?

14 of 64

續: 分散式系統的謬論

參見:#分散式系統的謬論 (Fallacies of distributed computing) 計算計科學家 Peter Deutsch 在九零年代就提出 Fallacies of distributed computing (分散式系統的謬論) ,點出以下容易被忽略、或者輕忽的觀點:

- The network is reliable (網路是可靠的)

- Latency is zero (網路沒有延遲)

- Bandwidth is infinite (頻寬是無限的)

- The network is secure (網路是安全的)

- Topology doesn’t change (網路拓墣不會改變)

- There is one administrator (網路上有個管理員)

- Transport cost is zero (傳輸沒有成本)

- The network is homogeneous (網路是同質的)

15 of 64

AWS 的 "API 授權" 備忘錄 (2002 年...)

從這份備忘錄,你看到了什麼?

表面上的解讀:

背後的意涵:

THINK: 你能滿足這些期待嗎?

貝佐斯 訂了一大堆規範...

禁止用不洽當的技術跨團隊溝通,目的是避免技術債

公司真正的資產是專業領域的資訊處理能力,API 才是最合適的提供服務的型態 (對內對外皆然)

這些條款的目的,都是保障公司的投資未來都能被內外部團隊充分的利用

API 串聯起來的是服務與服務間的連結,這是商業運作的骨幹。UI 只是啟動它的介面而已。

這些實在太重要了,最後只好說重話: "沒有討價還價的餘地,不遵守上面規定者,一律開除"

16 of 64

後面, 我們來聊聊這幾個主題:

API 的治理策略 (略)

API 的開發策略

// 服務的生命週期每個階段

// 該注意的面向盤點

// 團隊中該具備的角色

// 流程

// 設計方式

// 用好的設計提高安全性

// 預防過度設計

17 of 64

附註: 流程與決策順序改變,必須先改變團隊的文化與能力..

團隊如何轉型? 團隊與人才如何培養? 如何連結團隊的目標?

> 用讀書會讓關鍵人員先有 "knowledge", 因為很多事情是 "你不知道你不知道" 的階段..

> API 的設計、開發、使用都需要高度的抽象化思考。背景知識是很關鍵的基礎。

保哥提供的 [中文翻譯版] !!

18 of 64

2. API 的治理策略 (略)

// 策略沒有標準答案

// 盤點下列項目,想清楚你的團隊怎麼因應

19 of 64

API 的評量指標 (API使用、API註冊、客戶類型、影響、創意)

API 的生命週期 (建立、發表、實現、維護、除役)

API 的十大支柱 (策略、開發、設計、部署、文件、測試、安全防護、監控、發現、變動管理)

試問:

  1. 你們推動 API First 的主要目標是? 衡量指標是? 如何達到?
  2. 你們團隊是否有妥善的 API 生命週期管理流程?
  3. 你們團隊是否在十大支柱都有標準的作法或是 checklist?
  4. 你的團隊該要有那些角色來達成這些目標?

思考: 下列的 API 是否 "成功" "

  1. 如果你的 API 只有一個客戶在使用,但是它佔了營收的 30% ?
  2. 如果你的 API 叫好又叫座,有上百家客戶註冊並且持續好評,但是卻沒有對你的核心產品帶來收入?
  3. 如果你的 API 持續帶來收入,但是已經不符合你期待的商業模式了呢 ?

20 of 64

API 生命週期的五個階段

5. [除役]

  • 有已發表且可替代使用的API實例(新的、更好的替代品)
  • 它的實現價值已經低於維持成本
  • 已做出除役決定

  1. [建立]
  2. 它是一種新的API,或已經不復存在的API的替代品
  3. 它已經被部署在產品環境了
  4. 它還無法提供可靠的功能

4. [維護]

  • 它被一個或多個用戶端app積極地使用
  • 它的實現價值呈停滯或下降趨勢
  • 它已經不被積極改善了

<成長停滯或下降,可能代表API已經進入維護階段了,你必須定義關鍵指標評量週期,及停滯的門檻是什麼>

2. [發表]

  • 有API實例,已被部署到產品環境
  • 有一或多個開發者社群可以使用它
  • API的戰略價值尚未實現

3. [實現]

  • 有以發表且可使用的API實例
  • 用戶以實現API的目標方式使用它
  • 實現的價值成向上趨勢

21 of 64

API 產品週期與十大支柱

1 建立

2 發表

3 實現

4 維護

5 除役

策略

設計

開發

部署

文件

測試

安全防護

監控

發現

變動管理

  • 各產品週期階段如何影響API工作支柱
  • 管理工作支柱在各週期都有重要意義,但有些支柱在某些階段比其他支柱重要.

產品週期

十大支柱

22 of 64

一個 API 團隊中會有哪些角色?

    • 每個公司的職稱可能不同,但角色應該都相同
    • 每個角色代表著一個明確的責任範圍
    • 商務角色 vs 技術角色
  • API 產品經理
  • API 設計師
  • API 技術作者
  • API 倡議者
  • API 開發大使開發大使
  • 首席工程師
  • API 結構師
  • 測試工程師
  • 前端開發者
  • 後端開發者
  • DevOps工程師

23 of 64

👨‍💼 API 產品經理 ( API Product Manager )

  • 確保 API 有明確的目標 (OKR/KPI)
  • 確保 其他成員都有支援目前所需的支柱
  • 負責引導 API 走過五大產品週期
  • 負責定義&描述 API

🎨 API 設計師 ( API Designer )

  • 提供正面的開發者體驗
  • 反應用戶的聲音

✏️ API 技術作者( API Technical Writer )

  • 編寫 API 文件
  • 將資訊從 API 提供者傳遞給 API 用戶

🎤 API 倡議者 ( API Evangelist )

  • 對內提倡 API 文化
  • 對內宣傳 API 產品
  • 搜集、聆聽使者聲音。提高開發者體驗

🎉 開發大使 (Developer Relations, DevRel)

  • 對外宣傳 API
  • 負責“銷售” API 產品
  • 搜集、聆聽使者聲音。提高開發者體驗
  • 公開活動、部落格撰寫 …

24 of 64

🚩 首席工程師 ( Lead API Engineer )

  • 相當於技術端的 PM
  • 負責 API 實作的 how
  • 協調團隊的技術人員

🏗 API 結構師 ( API Architect )

  • 負責 API 結構設計細節
  • 確保 API 的設計能與其他系統良好互動
  • 整體的系統結構、安全性、穩定性指標

🖥 前端開發者( Fronetend Developer, FE )

  • 高品質的用戶體驗
  • API 後台

🛠 後端開發者( Backend Developer, BE )

  • 忠實執行 PM & API 設計師的設計
  • 確保 API 可靠、穩定、一致

🐝 測試工程師 ( Test / QA Engineer )

  • 負責測試功能、安全 & 穩定性

🔁 DevOps 工程師 ( DevOps Engineer )

  • 建構 & 部署
  • 製作 or 提供交付工具 (pipeline)
  • 管理發表計畫 (release plan)
  • 監控、審查、診斷

25 of 64

3. API 的開發策略

26 of 64

API First 對開發團隊而言最大的改變

( 越明顯的改變排越前面 )

開發流程的改變:

分析設計方式 & Ownership 的改變:

安全控管的改變:

  • contract first vs requirement first
  • 一切先從訂定 API 規格開始 (不是先寫 code)�

  • design api spec vs design function + database schema
  • 先從 domain 開始分析 ( action + model ), 而不是先從 database schema 開始
  • 每個服務 / API 都應該要有 owner, API 背後的細節都應該被封裝, 封裝才能降低整體系統溝通的複雜度�

  • scope + api-key vs function list + 授權 + 帳號
  • 由功能的開關, 轉變為領域操作的授權。
  • API 的安全性做的有多確實,決定了你整個生態系的安全性 (案例: 你相信 Oauth 的授權同意功能嗎?)

27 of 64

THINK…

該怎麼管控 API 的授權,你才能

夠 "安心" 的放上這段話?

28 of 64

3.1, 開發流程的改變

// 一切的改變, 都從 contract first 開始.

// 談 API 的規格, 比起 " interface ", 我覺得用 " contract " 更貼切

// 訂定好的 contract / interface, 抽象化思考是關鍵能力

29 of 64

Ruddy Lee, 淺談 API First, 2021/09/08

30 of 64

Ruddy Lee, 淺談 API First, 2021/09/08

Contract First, 先定義出介面與可呼叫的 Mock,

前後端快速 (asap) 的確認規格, 實際用 code 確認理解正確

架構師可已盡可能收集潛在案例, 用 mock 驗證可行性。

QA 可以 asap 開始先寫可執行的測試案例。

Tech Writer 可以開始按照規格撰寫文件與範例。

團隊可以開撰寫各種語言需要的 SDK。

有 QA 的可執行測試案例,有 Mock 當作對照,API 的開發可以用最低的風險進行

在符合 contract 的前題,以及按照 contract 開發的測項保護下,API 團隊可以放心地進行各種最佳化作業

31 of 64

思考: 你如何知道 API contract 開 "正確" 了?

(product first) 傳統的開發模式,你先寫 code, 先設計主要的 database schema, 能交付最基本的價值後, 開始不斷的重構, 然後交付對應的 API。

(api first) 先訂好 API spec, 確認無誤後:

0. 定義第一版的規格草案 (能有 swagger 更好)。架構師可以先用這規格試著評估能否用來面對需求?

1. 按照規格,開發 mock server (基本上有 swagger 就能 generate 出 80% 的版本了)。

2. Application 開發團隊,搭配 mock server 就能開始開發應用

3. 同時, API 開發團隊可以開始實做 API server

4. 同時, QA 可以開始針對 API 寫測試

5. (如果需要的話) SDK 的開發也可以同時進行

6. 整合測試..

這部分都能同時並行

// (我們做了才知道的關鍵) �// 比起效率,更重要的是: 你怎麼知道開對規格了?

32 of 64

Ruddy Lee, 淺談 API First, 2021/09/08

Contract First, 先定義出介面與可呼叫的 Mock,

前後端快速 (asap) 的確認規格, 實際用 code 確認理解正確

架構師可已盡可能收集潛在案例, 用 mock 驗證可行性。

QA 可以 asap 開始先寫可執行的測試案例。

確認設計的正確性:

我們 (尤其是架構師) 大量利用 Mock 來驗證各種

商業情境的可行性,在 Mock 就能模擬預期的結果

(例如結帳金額計算規則)。

由於經過大量簡化技術細節 (沒有簡化商業規則),架構師能夠在會議上直接用 code 寫商業情境並確認結果。

確認開發的正確性:

廣義的 TDD, 不只是 RD 在開發前應該先寫單元測試再寫程式,整個團隊也該要能提前準備自動化測試,隨時確保 RD 交付正確的服務。

33 of 64

我們的作法: design sprint, PoC 確認你的 contract works

將所有能夠簡化的東西都簡化 (或是降級),唯一的目的是驗證你的關鍵設計可行,高度抽象化是設計成功的關鍵。

// API 設計關鍵在 contract, 降級成 C# interface 就已足夠

// 將資料庫存取, 降級為 collection 操作

// 將 UI 互動介面, 降級為 console output

// 移除開發框架 (例如 DI, Logging), 只使用最基本的語法

將關注點放在 domain object, 簡化到用程式碼就足以描述你的情境, 執行後觀測結果, 驗證設計可行。

簡化至此, PoC 就能拿來在會議上討論定義並且當場修改, 確認符合需求提出者的期待。經過這樣的驗證,你可以放心相信你的 contract 值得信賴。

34 of 64

3.2, API 設計方式的改變與標準化

// 練習先找出關鍵的 API 結構,排除所有非必要的細節設計。

// 關鍵的 API 結構設計出來就可以先進行案例驗證,完成後再展開細節設計。

// 細節包括: 參數定義,實做技術選擇,可以事後用組合方式產生的 API 等等

35 of 64

設計 API 的核心結構 - 狀態機

找出你的 domain 最關鍵的行為 (不用急著找出所有的行為, 找出關鍵就夠了)

其實 OOP 的觀念掌握的徹底就很夠用。將服務降維思考 ( 物件 = states + method )

我們內部的作法: 用狀態機 + 實例化案例來確認 API 的骨架是否正確合理,再展開變成 spec

案例: 微服務架構 - 從狀態圖來驅動 API 的實作範例

思考: 為什麼要以狀態機為基礎?

> 狀態機 表達了資源的生命週期,你能清楚掌握資料何時應該被刪除

> 由於生命週期如此重要,因此掌握能改變資源狀態的所有動作,就是 API 該關注的主要結構

> 主要結構確認後,其他衍生的所有 API 都必須遵循主結構的約束

> 千萬不要: 找出資源,套上 CRUD 就變成 API… (直接拿 ORM + Code Gen 產生 API 還比較快)

36 of 64

步驟

1. 找出主要的 Entity(s), 或是 Resources (例如: 主要資料, 會員, 訂單, 商品等等, 或是處理單據)

2. 找出狀態轉移, 畫出狀態圖 ( FSM, Finite State Machine )

3. 標示狀態轉移 (箭頭) 時發生的動作 ( action, command )

4. 標示有哪些角色會呼叫你的服務, 這些角色能執行那些動作

5. 標示不會改變狀態的動作, 同樣標示有那些角色能夠執行

6. 標示那些動作會因為事件而觸發 (事件包含: action 完成, 狀態移轉完成)

==> 你的 API 主結構就已經完成了。

37 of 64

Overview and State Machine 狀態機

1. 畫出狀態機,列出所有狀態

2-1. 列出所有改變狀態的動作清單,這就是你第一版關鍵的 API, 執行後會改變狀態。

API: POST /api/members/{id}:{action}

2-2, 列出不會改變狀態的動作 (例如 Get)

API: GET /api/members/{id}:{action}

2-3, 列出其他為了 "好用" 而設計的 API。

這些 API 必須確保可由 (1) + (2) 組合而成,行為一致

Action (不改變狀態)

  • Get
  • Get-Masked
  • Get-Statistics

38 of 64

Overview and State Machine 狀態機 (續)

A

A

A

D

B

B

B

E

Event

Registering / Registered

(每個 action 執行中 / 完成)

StateChanged

4. 列出所有的事件

4-1. 每個 Action 進行中 (ing) 與已完成 (ed) 的事件。�事件參數至少包含: id, init-state, final-state

4-2. 每個 State 改變後的事件。

事件參數至少包含: id, init-state, final-state, action

事件實做的形式, 可由開發人員自行決定。常見的選擇有 Message Bus, 或是 WebHook.

3. 列出有哪些可能的角色會呼叫這些 API, 並且在圖上標示。這是未來權限管控的機制設計。

3-1. 未來核發 API-KEY 時, 這把 KEY 就應該標記是給哪種 Caller 使用的。Caller 可以再細分為 SCOPE, KEY 可以被授權多個 SCOPE

A

39 of 64

透過狀態機開出來的 API:

Register:

POST /api/members:register

Import: (追加)

POST /api/members:import

Verify:

POST /api/members/{id}:verify

Ban:

POST /api/members/{id}:ban

Recover:

POST /api/members/{id}:recover

Remove:

POST /api/members/{id}:remove

Get:

GET /api/members/{id}

// 你可以決定是否需要全部的事件

registering, registered, state_changed(unverified)

importing, imported, state_changed(unverified)

verifying, verified, state_changed(verified)

banning, banned, state_change(banned)

recovering, recovered, state_change(verified)

removing, removed, state_change(removed)

getting, getted

40 of 64

權限管制表

Action

Register

Verify

Ban

Recover

Remove

Caller

A. 會員本人

start:*

unverified:*

verified:*

B. 營運人員

verified:*

banned:*

banned:*

C. 營運主管

D. MS自己

banned:*

E. 3RD

start:*

權限管控,有很多種實做方式。

1. 你可以開帳號 (account),或是用角色 (role) 來代表 caller, 在實際執行 action 前就做出判斷,決定是否回應 403

2. 你也可以用 API KEY 加上 SCOPE 的授權方式來實做 (這是較為通用的作法)

Think: 如果我想控制 "只允許內部使用的 API", 我該怎麼做?

(可以收斂成數個 scope)

可以化簡為:�� APIKEY�+�SCOPE

41 of 64

API Access Scope 參考範例

42 of 64

API 需求資料/ Scenario

順序

Scenario

(who / when / what)

Provider

Caller

(誰要用)

Action

State

說明

S0-01

會員本人 (A) 尚未成為好好買的會員,在好好買網站上註冊。

ms

會員本人 (A)

register

Unverified

註冊帳號,尚未驗證

S0-01.1

系統偵測到註冊成功的事件後,自動發出 email 送出驗證連結

ms

(D) MS

event handler

Unverified

攔截註冊成功事件 (RegisterCompleteEvent),取得驗證碼送出信件

S0-02

會員本人 (A) 註冊帳號後,透過 email 驗證帳號。

ms

會員本人 (A)

verify

Verified

驗證帳號

S0-03

會員本人 (A) 買完商品並且到貨,物流需要會員的手機號碼及姓氏 (不須完整姓名) 以寄簡訊通知會員。

ms

(E) 3rd

get

Verified

1. 透過 #6 取得完整手機號碼

2. 透過 #7 取得姓氏

S0-04

會員本人 (A) 到超商取貨,超商需要會員的手機末三碼及姓氏 (不須完整姓名) 。

ms

(E) 3rd

get-mask

Verified

透過 #7 取得手機末三碼及姓氏

盡可能蒐集 API 可能要面對的案例�(用最困難,用最不典型的案例來驗證你的設計, 只要驗證成本夠低就不會有太多負面影響, 你會知道你的 API 泛用性有多廣)

按照順序,比對 action / status / caller 是否能如狀態機的標示運行,可用最低人力快速驗證 API 的設計是否符合期待。這個階段暫時可以先略過 API 的 request / response payload, 可留待後面階段再補上。

43 of 64

對比典型的 CRUD API:

Register:

POST /api/members:register

Import: (追加)

POST /api/members:import

Verify:

POST /api/members/{id}:verify

Ban:

POST /api/members/{id}:ban

Recover:

POST /api/members/{id}:recover

Remove:

POST /api/members/{id}:remove

Get:

GET /api/members/{id}

// 對比一下,典型的 CRUD REST API

Create: // 我該寫多少 if 才能分得出是註冊還是匯入?

POST /api/members

Read: // 我該怎麼判斷你是否只要讀取遮罩的個資?

GET /api/members/{id}

Update: // 我該怎麼判斷你更新資料的意圖?

PUT /api/members/{id}

PATCH /api/members/{id}

Delete: // 不同狀態允許不同 caller 刪除...

DELETE /api/members/{id}

// 這種 API 設計,你能夠控制權限嗎?

// 這種 API 設計,你有辦法觸發事件嗎?

// 這種 API 設計,觸發的事件對你有意義嗎? 只能拿來 SYNC?

44 of 64

思考: 我該按照 "目前" 還是 "未來" 的需求來開 API ?

如果 "只" 按照需求,那跟 Product First 有何不同 ?

如果 "要" 考慮未來需求,你如何確認不會過度設計 ?

善用各種分析技巧 ( DDD, OOA 都可以 ), 找出對的 API 結構

善用 PoC 的技巧 ( domain object 即可 ), 盡可能收集內外部期待的使用案例來驗證。

結構正確,比細節正確還重要。結構是否精準,影響了你的 API 是否夠 "穩定" ?

適合做這件事的角色:

👨‍💼 API 產品經理 ( API Product Manager )

  • 確保 API 有明確的目標 (OKR/KPI)
  • 確保 其他成員都有支援目前所需的支柱
  • 負責引導 API 走過五大產品週期
  • 負責定義&描述 API

🚩 首席工程師 ( Lead API Engineer )

  • 相當於技術端的 PM
  • 負責 API 實作的 how
  • 協調團隊的技術人員

45 of 64

46 of 64

3.3, 從 API 設計階段就考慮安全性

// 安全性的定義有很多,這邊的認定能被刻意利用,用來影響正常運作的任何因素都列入考慮

// 1. 能異動不該異動的資料

// 2. 能取得不該取得的資料

// 3. 正常操作就會影響系統可靠度的行為

47 of 64

設計 API 的安全機制: 授權管理

我們要談的,不是基礎建設的資安問題 (例如加密、二階段驗證等等)。而是 API 設計上是否讓商業邏輯本身就有漏洞可鑽?

授權管理的原則:

  1. 我們需要知道每一個 API 呼叫是來自哪個 caller … (常見做法: 替每個 caller 配發 API-KEY 識別)
  2. 發布的 API-KEY, 應該要標記對應的 caller 授權, 或是再將 caller 的授權拆分為 scope 授權.

安全風險考慮:

1. 會異動狀態的 API (會影響資料生命週期與系統正常運作)

2. 會異動資料的 API (會影響資料正確性)

3. 會取得個資或是機密資訊的 API (會外洩機密資料)

4. 會列舉資料 (大量) 的 API (會導致資料大量匯出、會嚴重影響效能)

回顧 access scope 的說明

48 of 64

搭配 API 相關的基礎建設: 認證管理

不論對內、對外都應該要有 API 通訊 (連線) 的管制措施。

常見的措施有:

1. 集中式的服務: API Gateway, API Management, Ingress

2. 協作式的服務: DNS (?), Service Discovery, ETCD

3. 分散式的服務: Service Mesh

對內 / 對外應該有不同的 API-KEY 管理機制:

1. 對外, 一組 APIKEY 代表一組合作關係 (合約? 訂閱?), KEY 代表使用這些授權的鑰匙

2. 對內, 一組 APIKEY 代表一個被認可的 Caller (團隊, 服務), 由授權服務來決定能用那些功能

49 of 64

不同的權限管控方式: 車票 v.s. 識別證

車票: 票本身標註了賦予了持票者能做的事情。

- 日期, 班次, 座位

- 進站, 出站

- 保佑

任何人拿到這張票,就可以

搭這班車。憑車票能做的事

早就已經印在票券本身。

識別證: 票券本身證明了持有者的身分

- 日期

- 持有者

任何人拿到這張識別證,就

會有人找你拍照 (並沒有)

憑識別證,能做什麼事情,

取決於提供服務那端自行

判定。

50 of 64

外部: 適合用 "車票" 的管理方式。

一個箭頭一個 APIKEY

內部: 適合用 "識別證" 的管理方式。

一個服務一個 CERT

51 of 64

以 API 為主要的跨團隊溝通方式: 控制效能與資料安全性

對比過去的做法: 共用資料庫,共用檔案,批次排程 + 資料抄寫,各種資料庫複寫的工具。改成 API 之後:

1. 以單筆的操作為主,由 ID 來執行單筆的資料操作,需要保證可靠度與回應時間

2. 多筆 (查詢,匯出) 的操作需要被限制或是隔離,包含安全與效能考量

3. 區分資料操作 ( OLTP ) 與資料查詢分析 ( OLAP ) 的隔離 ( 善用讀寫分離,CQRS,資料倉儲等 )

4. 一致性的問題需要經過設計 ( 分散式系統,冪等性,強一致性,資料鎖定 )

  • 冪等性的設計
  • 透過 API 執行交易的技巧,例如 2PC, Saga
  • // 沒有掌握這些技巧,你就別想脫離資料庫執行交易處理了... ( 會被貝佐斯 fired 掉... )

52 of 64

3.4, 思考是否會過度設計?

// 過與不及都是極端,團隊需要有足夠經驗與視野的人來決定平衡點

53 of 64

游舒帆, 商業思維學院 PO文, 2022/09/07

54 of 64

API First 是兼顧天平兩端的解方

API 應該最大化的往模組化靠攏,同時應該只保留關鍵功能,維持適度設計,最大化合理的彈性與系統管理。

有 API 加持的產品服務,就能放心安全的往完全客製化的光譜移動,甚至你可以推出多套產品。

背後共用 API,能最大化消除重覆與浪費,保持滿足需求與關鍵功能的一致性。

55 of 64

模組化與客製化中間的思考與選擇對很多人來說一直都是一個難題。

對工程師來說,多數時候我們會希望盡可能的模組化,但過度的模組化,超過了當前業務的需求時,那就會變成過度設計。開發資源反而沒有用在真正重要的任務上,沒有對齊公司當前的狀況,以及需要解決的問題。

其實模組化與客製化是個光譜,完全模組化或完全客製化都不是長期經營應該思考的方向。

完全模組化幾乎是不可能,因為你很難對未來的需由有完整的預期,一般都是邊推進邊設計,如果有人告訴你他的架構是在為未來保留彈性,那你一定要問他:「這些彈性是為哪些需求保留的?」

一個好的架構師在設計時不可能脫離產品或業務需求,如果他沒有花時間去看手邊的需求清單,也沒有跟業務、產品團隊討論過未來半年的需求,對產業的趨勢也沒有洞察。但他卻告訴你:「這是為未來保留彈性。」,那這種話千萬不要相信。

脫離市場需求的架構都是過度設計,過往在與工程師討論架構時,我總是會探討未來需求,有經驗的工程師與架構師知道哪些是屬於通用性功能,通常需要保留一定的彈性,但對於非通用性的功能,那就很考驗他的 domain know-how 跟對產品現況的掌握度了,而探討未來需求則會增加他們提早預留彈性的精準性。

回過頭來,當我們對未來需求的掌握度不足,那你就很難一步到位做到完全模組化。樂高積木是個高度模組化的產品,但每一年他都還是有持續推出新的部件。高度模組化,保留可擴充的彈性,也保留可以加入新的元素來改變既有產品的可能性,這會更貼近市場所需。

完全客製化,如果是超高單價而且獨一無二的商品,那不會有問題,例如某些領域大師的作品,可能很接近藝術品,那每個都是從無到有客製也不見得有問題。

但對多數產品來說,一開始為一家公司做全客製品,利潤可能很不錯,但隨著市場愈來愈成熟,競品會開始出現,平均價格很可能會開始下滑,而你並沒有透過模組化來提高生產效率與品質,那等同於花相同的時間與成本,卻賺到比本來更少的錢,這就導致利潤下滑了。

而你的競爭者們,很可能已經開始模組化生產,它們的生產效率跟品質都比你好,也能做到局部的客製化,那你的競爭力很可能在過程中逐步喪失。

之前張忠謀在談論台積電的競爭力時,他提到「台積電最強大的競爭力來自於客製化能力」。

在聽這句話時,不要忘記台積電還有兩個很強的優勢,第一是領先的技術,第二則是製程。它們在技術與製程上是高度模組化的,所以它們可以很快的拉出一條生產線來應對客製化產品,而且這個產線的成熟度是夠高的。

用很低的成本就能搞定客製化產線,交付的時間跟品質都贏過競爭對手,你說這背後的能力是怎麼來的?技術、製程才是支撐的重要元素。簡單的說,台積電是一家高度模組化的公司,而高度模組化的背後,也是它們對整個產業生態的掌握,領頭公司對未來需求的可預期性本來就比較強,它們的高度模組化就比較不容易掉入過度設計的陷阱中。

高度模組化,又具備很強的客製化能力,這是很多公司迫切期待的事,但中間的困難度從上面的描述就可見一斑啦。

為什麼說架構師與資深的產品設計師都需要具備很強的 domain know-how 以及產業、商業洞察能力?因為不具備這些,那它們的設計都會偏離公司未來業務所需。

模組化永遠是一個努力方向,尤其產品發展時間愈長,它的重要性就愈高,因為缺乏模組化設計的架構一般都是高度耦合的,而許多的技術債正是因為缺乏好的模組化設計而衍生。

沒有模組化,你會很難自動化,

沒有模組化,你也很難管好客製化,

沒有模組化,你甚至連團隊分工都會開始出問題。

模組化是一定要的,但客製化也是不可避免的。在服務為導向的商業世界裡,客戶需要的,永遠是為他量身打造的客製品。

這就是為什麼 架構師 應該在設計出 contract 時, 就盡可能的 POC 各種未來可能會碰到的需求,回來修正 contract 的原因。用很快的速度,很低的成本完成這些事,這就是架構師存在的價值。

56 of 64

4. 總結

// 今天既然是 DevOpsDays 的 KeyNotes, 結尾總要跟 DevOps 沾上一點關係...

57 of 64

除了持續改善,也要看見全貌

我們的視野

這才是全貌

要看到全貌,必要條件是有充分的� “資訊” 與 “知識”。

g(x)=-x4+5x3-7x2 +3x+1

58 of 64

回頭來想想 AWS 的軍規...

如果你的老闆也下達跟貝佐斯一樣的命令,那麼...

你 "該" 先設計功能? 還是 "該" 先思考 API?

你是先設計 API? 還是先設計 table schema?

你是先設計 Entity (json schema)? 還是先設計 table schema?

想看看,下列 API 難以面對的問題類型你會怎麼設計?

- Batch (massive process)

- Batch (long running)

- Batch (massive data import / export)

- Distributed Transaction

改變思路, API First 你應該要思考最關鍵的部分, 怎麼組合應用交給別人, 你該想想最關鍵的設計需要關注什麼

- solution: CLI + pipeline (不一定要硬幹啊)

- solution: Async API design, call & pooling | callback

- solution: based on reliable storage + async

- solution: 2 phase commit, Saga + local transaction

- 用 API 思考 (action), 不要用 UI + DB 思考 (function + database)

- 用 Entity 思考, 不要用 Table 思考 ( json vs table )

- 用狀態機思考, 不要用流程圖 / 循序圖思考 ( life cycle vs sequence )

59 of 64

DevOps 的精神,是快速交付價值,持續優化,持續迭代...

在不斷優化的過程中,往往眼裡只有 "改進",沒有 "變革" …

然而,API 的成熟非常仰賴 "規格" 的穩定性 (有人聽過: 海勒姆法則 / Hyrum's Law 嗎?)。

沒有脈絡的持續優化,難以在 API 的生態系下有健全的發展。

// 敏捷團隊,架構師是少數需要關注長期議題的角色,尤其在 API First 的生態下更為重要。

我從資工系學到的道理: 用計算機大量運算,很容易靠暴力法找到答案。不過沒有理論基礎的話,你找到的可能只是 "極大值",而不是 "最大值"。

有 "正確" 的結構,有札實的基礎,你的團隊才能有超凡的表現。

API First 講求的就是用正確的結構設計札實的 API, 把這樣的 API 設計擺在服務的第一順位,就是 API First 的精神。

60 of 64

這次直播,你覺得最大的收穫是什麼?

61 of 64

這次直播,你覺得最大的收穫是什麼?

62 of 64

感謝各位的參加.

63 of 64

64 of 64