committed by
GitHub
1 changed files with 482 additions and 0 deletions
@ -0,0 +1,482 @@ |
|||
# 替代方案、啟發與比較 |
|||
|
|||
是甚麼啟發了 **FastAPI**, 它與其他替代方案的比較,以及它從中學到了什麼。 |
|||
|
|||
## 前言 |
|||
|
|||
如果不是因為前人的努力,**FastAPI** 就不會因此而存在。 |
|||
|
|||
在 **FastAPI** 之前有許多工具被創造出來,這些工具啟發了它的誕生。 |
|||
|
|||
多年來,我一直避免創建一個新的框架。最初,我嘗試使用許多不同的框架、插件和工具來解決 FastAPI 所涵蓋的所有功能。 |
|||
|
|||
但在某個時間點,除了創造一個能夠提供所有這些功能的工具之外,已經沒有其他選擇了。這個工具從之前的工具中汲取了最好的想法,並以最佳的方式將它們結合起來,同時利用了以前無法使用的語言特性(Python 3.6+ 的型別提示)。 |
|||
|
|||
## 先前的工具 |
|||
|
|||
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> |
|||
|
|||
Django 是最受歡迎的 Python 框架,並且廣受信任。它被用來構建像 Instagram 這樣的系統。 |
|||
|
|||
它與關聯式資料庫(如 MySQL 或 PostgreSQL)的耦合度較高,因此將 NoSQL 資料庫(如 Couchbase、MongoDB、Cassandra 等)作為主要儲存引擎並不容易。 |
|||
|
|||
Django 的設計初衷是為了在後端生成 HTML,而不是為了建立供現代前端(如 React、Vue.js 和 Angular)或其他系統 (類似 <abbr title="Internet of Things">IoT</abbr> devices)使用的 API。 |
|||
|
|||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> |
|||
|
|||
Django REST Framework 是為了在 Django 的基礎上建構 Web API 而建立的靈活工具包,旨在提升其 API 功能。 |
|||
|
|||
它被許多公司使用,包括 Mozilla、Red Hat 和 Eventbrite。 |
|||
|
|||
它是自動生成 API 文件的早期範例之一,而這正是啟發「探索」FastAPI 的第一個想法之一。 |
|||
|
|||
/// note | 筆記 |
|||
|
|||
Django REST Framework 是 Tom Christie 所發明,他同時研發了 Starlette 和 Uvicorn,兩者皆是基於 **FastAPI**。 |
|||
|
|||
/// |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
提供自動生成的 API 文件化網頁使用者介面(Web UI)。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> |
|||
|
|||
Flask 是一個「微框架」,它並未內建資料庫整合功能,也不包含 Django 中預設提供的許多功能。 |
|||
|
|||
這種簡潔與靈活性,使得使用 NoSQL 資料庫作為主要資料儲存系統。 |
|||
|
|||
由於其設計極為簡潔,學習起來相對直觀,儘管其文件在某些部分仍需要點技術。 |
|||
|
|||
它也常被用於其他不一定需要資料庫、用戶管理或 Django 中預建的眾多功能之應用程式。儘管這些功能中的許多可以透過擴充套件來添加。 |
|||
|
|||
這種模組化的設計,以及作為一個可擴展以滿足特定需求的「微框架」,正是我希望保留的關鍵特性。 |
|||
|
|||
鑑於 Flask 的簡潔性,它似乎是構建 API 的理想選擇。接下來要尋找的,便是 Flask 的「Django REST Framework」。 |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
成為微框架,使其能夠輕鬆組合和搭配所需的工具與元件。 |
|||
|
|||
具備簡單且易於使用的路由系統。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> |
|||
|
|||
**FastAPI** 實際上並不是 Requests 的替代品。它們的應用範圍截然不同。 |
|||
|
|||
實際上,在 FastAPI 應用程式內部使用 Requests 是很常見的做法。 |
|||
|
|||
然而,FastAPI 仍然從 Requests 中獲得了不少靈感。 |
|||
|
|||
**Requests** 是一個用於與 API 互動(作為客戶端)的函式庫,而 **FastAPI** 則是一個用於構建 API(作為伺服器)的函式庫。 |
|||
|
|||
它們在某種程度上處於對立的兩端,彼此互補。 |
|||
|
|||
Requests 的設計非常簡潔且直觀,易於使用,並具有合理的預設值。但同時,它也非常強大且可自定義。 |
|||
|
|||
這就是為什麼官方網站上這樣說: |
|||
|
|||
> Requests 是有史以來下載量最多的 Python 套件之一 |
|||
|
|||
它的使用方式非常簡單。例如,要發送一個 'GET' 請求,你可以這樣寫: |
|||
|
|||
```Python |
|||
response = requests.get("http://example.com/some/url") |
|||
``` |
|||
|
|||
FastAPI 的對應 API 路徑操作可能會像這樣: |
|||
|
|||
```Python hl_lines="1" |
|||
@app.get("/some/url") |
|||
def read_url(): |
|||
return {"message": "Hello World"} |
|||
``` |
|||
|
|||
觀察 `requests.get(...)` 和 `@app.get(...)`的相似程度。 |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
* 擁有一個簡單且直觀的 API。 |
|||
* 在一個直觀且明確的方式,直接使用 HTTP 的 method names (operations)。 |
|||
* 提供合理的預設值,同時具備強大的自定義功能。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a> |
|||
|
|||
我從 Django REST Framework 中想要的主要功能是自動生成 API 文件。 |
|||
|
|||
後來我發現有一種標準可以用來記錄 API,使用 JSON(或 YAML,為 JSON 的擴展)來描述,稱為 Swagger。 |
|||
|
|||
而且已經有人為 Swagger API 創建了一個網頁用戶界面。因此,能夠為 API 生成 Swagger 文件,就能自動使用這個網頁用戶界面。 |
|||
|
|||
後來,Swagger 被移交給了 Linux 基金會,並更名為 OpenAPI。 |
|||
|
|||
這就是為什麼在談到 2.0 版本時,人們通常會說「Swagger」,而對於 3+ 版本則會說「OpenAPI」。 |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
採用並使用 API 規範的開放標準,而非自定義的架構。 |
|||
|
|||
並整合基於標準的用戶介面工具: |
|||
|
|||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> |
|||
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> |
|||
|
|||
這兩者之所以被選中,是因為它們相當流行且穩定,但若稍加搜尋,你會發現有數十種適用於 OpenAPI 的替代用戶介面(你也可以在 **FastAPI** 中使用這些工具)。 |
|||
|
|||
/// |
|||
|
|||
### Flask REST Framework |
|||
|
|||
市面上有多種 Flask 的 REST 框架,但在投入時間與精力進行調查後,我發現其中許多已經停止維護或被棄置,並且存在一些無法忽視的問題,使其難以滿足需求。 |
|||
|
|||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> |
|||
|
|||
API 系統所需的主要功能之一是資料 "<abbr title="又稱為marshalling、轉換">序列化</abbr>" 這是指將數據從程式碼(如 Python)中取出,並轉換成可以透過網路傳送的格式。例如,將包含資料庫數據的物件轉換為 JSON 物件,或將 'datetime' 物件轉換為字串等。 |
|||
|
|||
另一個 API 所需的重要功能是數據驗證,確保數據符合特定條件。例如,確保某個欄位是 int 類型,而不是隨機的字串。這對於接收的數據特別有用。 |
|||
|
|||
如果沒有數據驗證系統,你必須手動在程式碼中進行所有檢查。 |
|||
|
|||
這些功能正是 Marshmallow 所提供的主要功能。它是一個非常優秀的函式庫,我之前也經常使用它。 |
|||
|
|||
但 Marshmallow 是在 Python 型別提示(type hints)出現之前建立的。因此,要定義每個 <abbr title="數據應如何被組成的定義">schema</abbr> 你必須使用 Marshmallow 提供的特定工具和類別。 |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
使用程式碼自動定義「模式」(schemas),以提供資料型別與驗證功能。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> |
|||
|
|||
API 的一個重要功能是從請求中解析 "<abbr title="讀取並轉換 Python 資料">parsing</abbr>" 資料,並將其轉換為 Python 可用的格式。 |
|||
|
|||
Webargs 是一款能夠在多種框架(包括 Flask)上提供此功能的工具。 |
|||
|
|||
它內部使用 Marshmallow 來執行資料驗證,並且與 Marshmallow 出自相同的開發團隊。 |
|||
|
|||
這是一款優秀的工具,在 **FastAPI** 問世之前,我也曾大量使用它。 |
|||
|
|||
/// info | 資訊 |
|||
|
|||
Webargs 由與 Marshmallow 相同的開發團隊打造。 |
|||
|
|||
/// |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
實現對請求資料的自動驗證功能。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> |
|||
|
|||
Marshmallow 和 Webargs 提供驗證、解析與序列化作為插件。 |
|||
|
|||
但仍然缺乏文件化功能,於是 APISpec 應運而生。 |
|||
|
|||
它是一個適用於多個框架的插件(Starlette 也有對應的插件)。 |
|||
|
|||
其運作方式是開發者在處理路由的函式內,透過 docstring 以 YAML 格式撰寫結構定義,然後 APISpec 會根據這些定義產生 OpenAPI 規範。 |
|||
|
|||
這種方式適用於 Flask、Starlette、Responder 等框架。 |
|||
|
|||
然而,這又帶來了一個問題,即需要在 Python 字串內使用 YAML 這種微語法。 |
|||
|
|||
編輯器對此的支援有限,並且如果修改了參數或 Marshmallow 的 schema 而忘記更新 YAML docstring,則生成的 API 文件可能會過時。 |
|||
|
|||
/// info | 資訊 |
|||
|
|||
APISpec 是 Marshmallow 相同的開發團隊所創建。 |
|||
|
|||
/// |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
支援 API 的開放標準 OpenAPI。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a> |
|||
|
|||
這是一個 Flask 的擴充套件,將 Webargs、Marshmallow 和 APISpec 整合在一起。 |
|||
|
|||
它利用 Webargs 和 Marshmallow 提供的數據驗證與解析功能,透過 APISpec 自動產生 OpenAPI 規範。 |
|||
|
|||
這是一個極為實用但尚未廣受關注的工具。它應該比許多 Flask 插件更受歡迎,可能因為其文件過於簡潔和抽象。 |
|||
|
|||
此工具解決了在 Python docstring 內撰寫 YAML(另一種語法)的問題。 |
|||
|
|||
在 **FastAPI** 出現之前,我最喜歡的後端技術組合就是 Flask、Flask-apispec 搭配 Marshmallow 和 Webargs。 |
|||
|
|||
這套技術組合促成了多個 Flask 全端應用程式生成器的開發,我與多個外部團隊長期使用這些技術: |
|||
|
|||
* <a href="https://github.com/tiangolo/full-stack" class="external-link" target="_blank">https://github.com/tiangolo/full-stack</a> |
|||
* <a href="https://github.com/tiangolo/full-stack-flask-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchbase</a> |
|||
* <a href="https://github.com/tiangolo/full-stack-flask-couchdb" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchdb</a> |
|||
|
|||
這些全端應用程式生成器也是 [**FastAPI** Project Generators](project-generation.md){.internal-link target=_blank} 的基礎。 |
|||
|
|||
/// info | 資訊 |
|||
|
|||
Flask-apispec 由與 Marshmallow 相同的開發團隊所創建。 |
|||
|
|||
/// |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
從原本的定義序列化與驗證的程式碼中,自動生成 OpenAPI schema。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (and <a href="https://angular.io/" class="external-link" target="_blank">Angular</a>) |
|||
|
|||
這甚至不是 Python 框架,NestJS 是一個基於 JavaScript(TypeScript)的 Node.js 框架,靈感來自 Angular。 |
|||
|
|||
它實現了類似於 Flask-apispec 的功能。 |
|||
|
|||
它內建一套依賴注入(Dependency Injection)系統,靈感來自 Angular 2。與其他依賴注入系統一樣,它需要事先註冊「可注入項目(injectables)」,這導致程式碼變得更冗長且重複。 |
|||
|
|||
因為參數是用 TypeScript 型別(類似 Python 型別提示)來描述的,因此編輯器支援相當良好。 |
|||
|
|||
但由於 TypeScript 型別在編譯後不會保留於 JavaScript,因此無法同時用來定義驗證、序列化與文件化。 |
|||
|
|||
由於這一點及其他設計考量,要實現驗證、序列化與自動模式生成,需要在許多地方添加裝飾器,這導致程式碼變得冗長。 |
|||
|
|||
此外,它無法很好地處理巢狀模型。如果請求中的 JSON 主體包含內部欄位,而這些內部欄位本身又是巢狀的 JSON 物件,那麼這些巢狀結構可能無法正確地被文件化與驗證。 |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
使用 Python 型別來獲得更強大的編輯器支援。 |
|||
|
|||
設計一個強大的依賴注入系統,並設法減少程式碼重複。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a> |
|||
|
|||
這是一個基於 `asyncio` 極快的 Python 框架,與 Flask 非常相似。 |
|||
|
|||
/// note | 技術層面細節 |
|||
|
|||
它使用了 <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a> 而非 Python 預設的 `asyncio` loop。這也是讓它速度之快的原因。 |
|||
|
|||
它很明顯的啟發了 Uvicorn 和 Starlette,兩者在效能測試速度皆優於 Sanic。 |
|||
|
|||
/// |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
找到一個可以有非常高效能的方法。 |
|||
|
|||
這也是為甚麼 **FastAPI** 是基於 Starlette,因為它是目前最快的框架(由第三方效能測試測試後)。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> |
|||
|
|||
Falcon 是另一個高效能的 Python 框架,設計簡潔,並作為 Hug 等其他框架的基礎。 |
|||
|
|||
它的設計方式是讓函式接收兩個參數:「請求(request)」與「回應(response)」,然後從請求中讀取數據,並寫入回應。 |
|||
|
|||
因此,無法使用標準 Python 型別註記來宣告請求參數與主體。 數據驗證、序列化與文件化必須手動編寫,或是透過像 Hug 這類基於 Falcon 的框架來實現。 |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
尋找方法以獲得優秀的效能。 |
|||
|
|||
與 Hug 一樣(因為 Hug 是基於 Falcon 的),啟發 FastAPI 讓函式可選擇性地使用 response 參數來設置標頭、cookie 和狀態碼。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> |
|||
|
|||
我在建立 FastAPI 的初期發現了 Molten,它的設計理念與 FastAPI 相當相似: |
|||
|
|||
* 基於 Python 型別註解(type hints)。 |
|||
* 透過型別自動執行驗證與文件生成。 |
|||
* 內建依賴注入系統。 |
|||
|
|||
然而,Molten 並未採用像 Pydantic 這樣的第三方資料驗證、序列化與文件生成工具,而是內建了一套自己的解決方案。因此,定義的資料型別無法像 Pydantic 那樣輕鬆地被重複使用。 |
|||
|
|||
此外,Molten 需要較為冗長的設定,且它是基於 WSGI(而非 ASGI),因此無法充分利用 Uvicorn、Starlette 和 Sanic 等工具所提供的高效能特性。 |
|||
|
|||
Molten 的依賴注入系統要求先行註冊所有相依性,並且是根據所宣告的型別來解析相依性。因此,不允許有多個「元件」提供相同的型別。 |
|||
|
|||
路由定義則是集中在單一位置,並使用在其他地方定義的函式來處理請求,而非像 Flask 或 Starlette 那樣透過裝飾器(decorator)直接將路由與處理函式綁定在一起。這種方式與 Django 的作法較為相似,但它將程式碼中關聯性較高的部分分開處理,可能影響可讀性與維護性。 |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
Molten 的一個設計概念啟發了 FastAPI 允許透過模型屬性的「預設值」來定義額外的資料驗證規則。這樣的做法能夠提升編輯器的支援度,而在當時的 Pydantic 中尚未支援。 |
|||
|
|||
此概念後來也促使 Pydantic 進行改進,加入了相同的驗證宣告風格。目前,Pydantic 已經完全支援此功能。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a> |
|||
|
|||
Hug 是最早使用 Python 型別提示(type hints) 來宣告 API 參數類型的框架之一。這個創新理念啟發了許多後續工具的發展。 |
|||
|
|||
雖然 Hug 使用的是自訂型別而非標準 Python 型別,但這仍然是一大進步。 |
|||
|
|||
Hug 也是最早支援 自動生成 API 模式(schema) 的框架之一,能夠以 JSON 格式定義整個 API。 |
|||
|
|||
然而,Hug 沒有基於 OpenAPI 或 JSON Schema 標準,這使得它較難與 Swagger UI 等其他工具整合。但即便如此,它仍然是一個相當創新的設計。 |
|||
|
|||
Hug 也具備一個罕見而有趣的功能:同時支援 API 與 CLI 應用程式的開發,讓開發者可以用相同的框架來構建不同類型的應用。 |
|||
|
|||
由於 Hug 採用了 WSGI(同步 Python Web 框架的舊標準),它無法處理 WebSockets 等非同步功能,但仍然具有高效能。 |
|||
|
|||
/// info | 資訊 |
|||
|
|||
Hug 由 Timothy Crosley 創建,他同時也是 <a href="https://github.com/timothycrosley/isort" class="external-link" target="_blank">`isort`</a> 的作者。 |
|||
是一款自動整理 Python import 語句的優秀工具。 |
|||
|
|||
/// |
|||
|
|||
/// check | 一些啟發 **FastAPI** 的點子 |
|||
|
|||
Hug 啟發了 APIStar 的部分設計,也與 APIStar 一起,成為當時最具潛力的框架之一。 |
|||
|
|||
Hug 的創新理念對 FastAPI 產生了直接影響,特別是使用 Python 型別提示來宣告參數,以及自動生成 API 模式(schema)。 |
|||
|
|||
此外,Hug 也啟發了 **FastAPI** 在函式中宣告 `response` 參數,以設定 回應標頭(headers)與 cookies。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5) |
|||
|
|||
在我打算建構 **FastAPI** 前我發現了 **APIStar** 伺服器。它擁有了幾乎我所需要的一切功能,而且還有良好的設計。 |
|||
|
|||
它是我見過最早使用 Python 型別提示(type hints)來宣告參數與請求的框架之一(比 NestJS 和 Molten 還早)。我大約在發現 Hug 的同時也接觸到了它。但 APIStar 採用了 OpenAPI 標準。 |
|||
|
|||
它能夠自動進行資料驗證、資料序列化,並且根據相同的型別提示在多個地方生成 OpenAPI 模式(schema)。 |
|||
|
|||
不過,APIStar 的請求體(Body)架構定義並不像 Pydantic 那樣直接使用 Python 型別提示,而是更接近 Marshmallow。因此,編輯器的支援性相對較差,但即便如此,當時 APIStar 仍是最好的選擇。 |
|||
|
|||
當時,它的基準測試(Benchmark)表現最佳,只有 Starlette 能超越它。 |
|||
|
|||
最初,它沒有自動生成 API 文件的 Web UI,但我知道可以手動加入 Swagger UI 來補足這項功能。 |
|||
|
|||
它也具備依賴注入(Dependency Injection)系統,雖然需要事先註冊元件(與前面提到的工具類似),但這仍然是一個相當實用的功能。 |
|||
|
|||
然而,我從未能在完整的專案中使用它,因為它沒有內建安全性整合,無法取代我當時透過 Flask-apispec 全端生成器所具備的完整功能。我原本計畫提交一個 Pull Request 來新增這項功能,但後來,這個專案的發展方向發生了變化。 |
|||
|
|||
它不再是一個 API Web 框架,因為作者需要專注於 Starlette。 |
|||
|
|||
如今,APIStar 只是一組用來驗證 OpenAPI 規範的工具,而不再是 Web 框架了。 |
|||
|
|||
/// note | 筆記 |
|||
|
|||
APIStar 是由 Tom Christie 創建的。他同時也是以下專案的作者: |
|||
|
|||
* Django REST Framework |
|||
* Starlette (**FastAPI** 的基礎) |
|||
* Uvicorn (被 Starlette 和 **FastAPI** 使用) |
|||
|
|||
/// |
|||
|
|||
/// check | 啟發了 **FastAPI** |
|||
|
|||
在 Python 型別中同時宣告資料驗證、序列化和文件生成,並且提供極佳的編輯器支援,這對我來說是個天才般的設計。 |
|||
|
|||
我花了很長時間尋找類似的框架,並測試了許多不同的選擇,當時 APIStar 是最好的選項。 |
|||
|
|||
然而,APIStar 最終停止作為伺服器框架存在,而 Starlette 被創建,成為這類系統的新且更好的基礎。這成為我開發 **FastAPI** 的最終靈感來源。 |
|||
|
|||
我將 **FastAPI** 視為 APIStar 的「精神續作」,並在其基礎上改進與擴展功能、型別系統及其他部分,吸取了所有這些前人工具的經驗與優點。 |
|||
|
|||
/// |
|||
|
|||
## 被 **FastAPI** 所使用的 |
|||
|
|||
### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> |
|||
|
|||
Pydantic 是一個基於 Python 型別提示(type hints)來定義資料驗證、序列化與文件(使用 JSON Schema)的函式庫。 |
|||
|
|||
這讓它變得極為直觀易用。 |
|||
|
|||
它可與 Marshmallow 相提並論,但在效能測試中表現更快。此外,因為它同樣基於 Python 型別提示,編輯器支援性極佳。 |
|||
|
|||
/// check | **FastAPI** 透過 Pydantic 來處理: |
|||
|
|||
資料驗證、 資料序列化和自動生成模型文件(基於 JSON Schema)。 |
|||
|
|||
接著,**FastAPI** 會將這些 JSON Schema 數據整合進 OpenAPI,除了這些功能外,還執行許多其他任務。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> |
|||
|
|||
Starlette 是一個輕量級的 ASGI <abbr title="The new standard for building asynchronous Python web applications">ASGI</abbr> 框架/工具集,非常適合用來構建高效能的 asyncio 服務。 |
|||
|
|||
它設計簡單直觀,易於擴展,並擁有模組化的元件。 |
|||
|
|||
Starlette 的特色: |
|||
|
|||
* 極佳的效能表現 |
|||
* 支援 WebSocket |
|||
* 執行中的背景任務(In-process background tasks) |
|||
* 應用啟動與關閉事件(Startup & shutdown events) |
|||
* 基於 HTTPX 的測試客戶端 |
|||
* 支援 CORS、GZip、靜態文件、串流回應 |
|||
* 內建 Session 與 Cookie 支援 |
|||
* 100% 測試覆蓋率 |
|||
* 100% 型別註解(Type Annotation)代碼 |
|||
* 極少的硬性依賴 |
|||
|
|||
Starlette 是目前測試過最快的 Python 框架,唯一能超越它的是 Uvicorn,但 Uvicorn 並非框架,而是伺服器。 |
|||
|
|||
Starlette 提供所有基礎的 Web 微框架功能。 |
|||
|
|||
但它不具備自動資料驗證、序列化或文件生成功能。 |
|||
|
|||
這正是 **FastAPI** 在其基礎上額外提供的關鍵特性,透過 Pydantic 與 Python 型別提示來實現。此外,**FastAPI** 還加入了 依賴注入系統、內建安全工具、OpenAPI 架構生成 等功能,使其更強大與易用。 |
|||
|
|||
|
|||
/// note | 技術層面細節 |
|||
|
|||
ASGI 是由 Django 核心團隊成員開發的一種新的「標準」,目前尚未正式成為 Python 官方標準(PEP),但相關流程已在進行中。 |
|||
|
|||
儘管如此,ASGI 已經被許多工具採用為標準,大幅提升了不同工具間的互通性。 例如,你可以用 Daphne 或 Hypercorn 來替換 Uvicorn,或者加入 ASGI 相容工具,像 `python-socketio`. |
|||
|
|||
/// |
|||
|
|||
/// check | **FastAPI** 使用它來 |
|||
|
|||
FastAPI 使用 ASGI 來處理所有核心的 Web 功能,並在其基礎上增加額外功能。 |
|||
|
|||
其 `FastAPI` 類別直接繼承自 `Starlette`類別。 |
|||
|
|||
因此,任何可以在 Starlette 上做的事情,都可以直接在 **FastAPI** 上做,因為 FastAPI 本質上就是增強版的 Starlette。 |
|||
|
|||
/// |
|||
|
|||
### <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a> |
|||
|
|||
Uvicorn 是一款極速的 ASGI 伺服器,基於 uvloop 和 httptools 架構而成。 |
|||
|
|||
它並不是一個網頁框架,而是一個伺服器。例如,它不提供路徑導向的路由功能,這部分需要像 Starlette 或 **FastAPI** 這類框架來實現。 |
|||
|
|||
|
|||
Uvicorn 是 Starlette 和 **FastAPI** 官方推薦的伺服器。 |
|||
|
|||
/// check | **FastAPI** recommends it as |
|||
|
|||
運行 **FastAPI** 應用程式的主要網頁伺服器。 |
|||
|
|||
此外,你還可以使用 `--workers` 指令選項,啟動非同步的多行程伺服器,以提升效能。 |
|||
|
|||
更多詳細資訊請參考[部署](deployment/index.md){.internal-link target=_blank}章節。 |
|||
|
|||
/// |
|||
|
|||
## 效能測試與速度 |
|||
|
|||
如需瞭解、比較並觀察 Uvicorn, Starlette 和 FastAPI,請前往[基準測試](benchmarks.md){.internal-link target=_blank}. |
Loading…
Reference in new issue