<commit_before>---
layout: post
title: "微服務架構 - 從 API 的設計來看微服務"
categories:
- "系列文章: 微服務架構"
tags: ["系列文章", "架構師的修練", "microservices"]
published: true
comments: true
redirect_from:
logo: /wp-content/images/2022-03-25-microservices15-api-design/2022-03-27-15-03-23.png
---

這次我直接破題了。我想寫一篇從 State Machine 的分析為主軸，來驅動整個服務的 API 設計的文章。

![](/wp-content/images/2022-03-25-microservices15-api-design/2022-03-27-15-03-23.png)
> 圖片來源: https://www.giga.de/artikel/was-ist-eine-api-schnell-erklaert/

"我們服務的 API 設計很糟糕，怎樣才能設計出好的 API? 有沒有一些 SOP 或是準則可以給我參考?"

其實這個問題我已經被問到爛了，答案當然是 "沒有" 啊 XDDD, 如果有的話，這個問題根本就不會是個難題，也不會有這 FAQ 了。首先，API 的好壞，"設計" 占了九成以上啊! 設計問題是沒有正確答案的，既然是設計，就是帶有個人風格的，你會發現有些大師的設計就是既精準又靈活，看的到背後的巧思，每個環節都搭配的恰到好處，找不出一絲多餘的設計。指南 (Guideline) 通常是告訴你該做什麼，不該做什麼。它可以讓你設計出及格的 API，但是沒辦法讓你設計出理想的 API。要達到這個境界 (我也還不夠格) 需要依靠的是對 domain 更精準的掌握...。

先定義一下，何謂 "好" 的 API? 我很看重 API 設計上的一致性。API 必須顧及很多層面，例如你要端出那些功能? 這些功能是否都用一樣的視角來設計? (主詞會不會一直變動?) 背後處理的邏輯是否一致? (某個 API 不准你取得的資訊，另一個 API 卻又可以?) 你能否在呼叫前就很明確的知道能不能這樣用? (還是任何大小事都要查文件才能搞懂?)

其實這些細節都很煩人啊! 這些都是很多不同面向的考量，我們在實作時同個面向的問題往往都能很一致的處理，不同面向的一致性往往就因為背後的實作階段不同，就很容易被忽略。因此我蠻重視在設計階段就先想辦法對齊這些不同面向的問題。我的作法是，通通都在狀態圖上面把這些 API 設計的要素標示出來，在同一張圖上面思考，就很容易在設計階段解決一致性問題。


<!--more-->

會這樣做的原因很簡單，要設計好的 API，設計者一定要對 domain 掌控得很精準才有可能。用 DDD (Domain Driven Development) 是目前最理想的做法。不過，DDD 對非開發人員來說門檻有點高啊，我想在複雜度沒那麼高的情況下，讓 SA / PM 這些非開發人員也能設計出一致性高的 API 的做法 (一致性的範圍包含: 命名, 規則, 狀態, 動作, 事件, 授權)。另外，授權管控的設計越來越重要，我也希望在設計之初就能考慮進去。即使不是直接寫 code 的角色，我相信大部分的 PM / SA 都有能力理解狀態圖吧! 因此我自己逐步發展出透過 FSM (正規的名詞: 有限狀態機, [Finite State Machine](https://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA), 以下都簡稱 FSM) 就能把這些面向的結構都找出來的簡易做法。大部分的服務都不是單純的功能，而是都會針對某個主體 (Entity) 來提供相關服務。提供的方式有 API (主動呼叫) 或是 Event / WebHook (回呼), 這些服務的運作也需要有基本的授權管控。我認為 API 的設計，狹義的就是 API 規格了，廣義的是上述這些 (狀態、操作、事件、授權) 整個應該是一體，一致的設計，最後才實作成一個微服務。

這篇我就從 FSM 開始，以 FSM 為主導出整個服務介面設計的過程給大家參考。



{% include series-2016-microservice.md %}

# 前言

微服務，溝通的管道，就是要靠 API。但是什麼才是 "理想" 的 API 設計?

我現在的主要角色，是在公司的產品開發團隊擔任架構師，架構的設計我是擺第一位。API 的設計結構一旦複雜，他被使用的方式或順序就會難以預測，一不小心就會被有 "創意" 的人惡意使用，結果就往往會出乎你意料之外 (當然造成的後果跟損失也會意料之外)，然後資安或是漏洞就發生了。最近公司相關專案也在推動 API 的改善，我趁著記憶還清楚的時候紀錄一下我們自己團隊的作法好了。我通常用這幾個層次 (按照順序)，來評斷 API 設計的品質:

1. 結構設計是否明確清晰 (狀態, 領域知識, 設計的一致性)
2. API 規格是否符合業界慣例 (API style, 資源導向 / RPC 導向, 文件..)<commit_msg>change title<commit_after>---
layout: post
title: "微服務架構 - 從狀態圖來驅動 API 的設計"
categories:
- "系列文章: 微服務架構"
tags: ["系列文章", "架構師的修練", "microservices"]
published: true
comments: true
redirect_from:
logo: /wp-content/images/2022-03-25-microservices15-api-design/2022-03-27-15-03-23.png
---

這次我直接破題了。我想寫一篇從 State Machine 的分析為主軸，來驅動整個服務的 API 設計的文章。

![](/wp-content/images/2022-03-25-microservices15-api-design/2022-03-27-15-03-23.png)
> 圖片來源: https://www.giga.de/artikel/was-ist-eine-api-schnell-erklaert/



"我們服務的 API 設計很糟糕，怎樣才能設計出好的 API? 有沒有一些 SOP 或是準則可以給我參考?"

其實這個問題我已經被問到爛了，答案當然是 "沒有" 啊 XDDD, 如果有的話，這個問題根本就不會是個難題，也不會有這 FAQ 了。首先，API 的好壞，"設計" 占了九成以上啊! 設計問題是沒有正確答案的，既然是設計，就是帶有個人風格的，你會發現有些大師的設計就是既精準又靈活，看的到背後的巧思，每個環節都搭配的恰到好處，找不出一絲多餘的設計。指南 (Guideline) 通常是告訴你該做什麼，不該做什麼。它可以讓你設計出及格的 API，但是沒辦法讓你設計出理想的 API。要達到這個境界 (我也還不夠格) 需要依靠的是對 domain 更精準的掌握...。

先定義一下，何謂 "好" 的 API? 我很看重 API 設計上的一致性。API 必須顧及很多層面，例如你要端出那些功能? 這些功能是否都用一樣的視角來設計? (主詞會不會一直變動?) 背後處理的邏輯是否一致? (某個 API 不准你取得的資訊，另一個 API 卻又可以?) 你能否在呼叫前就很明確的知道能不能這樣用? (還是任何大小事都要查文件才能搞懂?)

其實這些細節都很煩人啊! 這些都是很多不同面向的考量，我們在實作時同個面向的問題往往都能很一致的處理，不同面向的一致性往往就因為背後的實作階段不同，就很容易被忽略。因此我蠻重視在設計階段就先想辦法對齊這些不同面向的問題。我的作法是，通通都在狀態圖上面把這些 API 設計的要素標示出來，在同一張圖上面思考，就很容易在設計階段解決一致性問題。


<!--more-->

會這樣做的原因很簡單，要設計好的 API，設計者一定要對 domain 掌控得很精準才有可能。用 DDD (Domain Driven Development) 是目前最理想的做法。不過，DDD 對非開發人員來說門檻有點高啊，我想在複雜度沒那麼高的情況下，讓 SA / PM 這些非開發人員也能設計出一致性高的 API 的做法 (一致性的範圍包含: 命名, 規則, 狀態, 動作, 事件, 授權)。另外，授權管控的設計越來越重要，我也希望在設計之初就能考慮進去。即使不是直接寫 code 的角色，我相信大部分的 PM / SA 都有能力理解狀態圖吧! 因此我自己逐步發展出透過 FSM (正規的名詞: 有限狀態機, [Finite State Machine](https://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA), 以下都簡稱 FSM) 就能把這些面向的結構都找出來的簡易做法。大部分的服務都不是單純的功能，而是都會針對某個主體 (Entity) 來提供相關服務。提供的方式有 API (主動呼叫) 或是 Event / WebHook (回呼), 這些服務的運作也需要有基本的授權管控。我認為 API 的設計，狹義的就是 API 規格了，廣義的是上述這些 (狀態、操作、事件、授權) 整個應該是一體，一致的設計，最後才實作成一個微服務。

這篇我就從 FSM 開始，以 FSM 為主導出整個服務介面設計的過程給大家參考。這篇我也把他歸類到微服務架構的系列文章了，因為 API 是微服務最重要的溝通管道啊，良好的 API 設計絕對是必要條件之一。如果你正在傷腦筋這些問題，請繼續看下去!



{% include series-2016-microservice.md %}

# 前言

微服務，溝通的管道，就是要靠 API。但是什麼才是 "理想" 的 API 設計?

我現在的主要角色，是在公司的產品開發團隊擔任架構師，架構的設計我是擺第一位。API 的設計結構一旦複雜，他被使用的方式或順序就會難以預測，一不小心就會被有 "創意" 的人惡意使用，結果就往往會出乎你意料之外 (當然造成的後果跟損失也會意料之外)，然後資安或是漏洞就發生了。最近公司相關專案也在推動 API 的改善，我趁著記憶還清楚的時候紀錄一下我們自己團隊的作法好了。我通常用這幾個層次 (按照順序)，來評斷 API 設計的品質:

1. 結構設計是否明確清晰 (狀態, 領域知識, 設計的一致性)
2. API 規格是否符合業界慣例 (API style, 資源導向 / RPC 導向, 文件..)
{'fraction_non_alphanumeric': 0.12559652928416487, 'fraction_numerical': 0.0316702819956616, 'mean_word_length': 7.353260869565218, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3429702', 'n_tokens_mistral': 4097, 'n_tokens_neox': 4681, 'n_words': 342}