FastAPI 的崛起,回應了現代 Web 開發對高效能、易用性及可擴充套件性框架的需求。它根據 Starlette 和 Pydantic,具備媲美 Node.js 和 Go 的效能,並以簡潔的程式碼、自動化 API 檔案和強型別支援等特性,簡化開發流程。其非同步處理能力有效提升應用並發性,使其成為構建 RESTful API 和處理大量請求的理想選擇。FastAPI 的自動化檔案生成功能簡化了 API 的使用說明和整合,而 Python 型別提示則強化了程式碼可讀性和穩定性,減少執行錯誤。從資料模型設計到身份驗證機制,FastAPI 提供了現代 Web 開發所需的各種工具,讓開發者能更專注於業務邏輯的實作。
現代 Web 開發的新趨勢:FastAPI 的崛起
前言
在現代 Web 開發領域中,開發者對於高效能、易用性以及可擴充套件性的框架需求日益增加。FastAPI 作為一個相對較新的 Python Web 框架,以其卓越的效能和簡潔的程式碼吸引了越來越多的開發者。本文將探討 FastAPI 的核心特性,以及它在現代 Web 開發中的應用。
FastAPI 簡介
FastAPI 是一個用於構建 API 的現代、快速(高效能)的 Web 框架,根據 Python 3.7+ 開發。它不僅支援非同步請求處理,還具備自動化的 API 檔案生成功能。FastAPI 的設計理念是簡潔、直觀且易於使用,同時確保了高效能和可靠性。
FastAPI 的核心特性
1. 高效能
FastAPI 根據 Starlette 和 Pydantic 構建,能夠提供與 Node.js 和 Go 相媲美的效能。這使得它成為構建高效能 API 的理想選擇。
2. 簡潔的程式碼
FastAPI 的 API 定義簡潔明瞭,大大減少了程式碼量。例如,使用 FastAPI 定義一個簡單的 API 只需幾行程式碼:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
內容解密:
- 這段程式碼首先匯入了
FastAPI類別,並建立了一個FastAPI應使用案例項。 - 使用
@app.get("/")裝飾器定義了一個處理 GET 請求的路由,路徑為根目錄/。 read_root函式傳回了一個 JSON 物件{"Hello": "World"}。
3. 自動化 API 檔案
FastAPI 能夠自動生成 API 檔案,支援 Swagger UI 和 ReDoc。這使得開發者和使用者能夠輕鬆理解 API 的使用方法。
4. 強型別支援
FastAPI 利用 Pydantic 進行資料驗證和解析,支援 Python 的型別提示(Type Hints)。這不僅提高了程式碼的可讀性,還減少了執行時的錯誤。
FastAPI 在現代 Web 開發中的應用
1. RESTful API 設計
FastAPI 非常適合用於構建 RESTful API。它的路由定義清晰,支援多種 HTTP 方法,並且能夠自動處理請求和回應的序列化。
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
內容解密:
- 定義了一個
Item模型,使用 Pydantic 的BaseModel。 update_item函式處理 PUT 請求,路徑引數item_id和請求體item被自動解析。- 傳回一個包含更新後專案名稱和 ID 的 JSON 物件。
2. 非同步處理
FastAPI 原生支援非同步請求處理,能夠有效提高應用的並發處理能力。
import asyncio
@app.get("/async")
async def read_async():
await asyncio.sleep(1)
return {"message": "Async operation completed"}
內容解密:
read_async函式是一個非同步函式,使用async和await關鍵字。asyncio.sleep(1)模擬了一個耗時的操作,實際應用中可以替換為真正的非同步任務。
FastAPI實務開發:從基礎到進階的全面解析
FastAPI作為新一代Python Web框架,以其卓越的效能、直觀的API設計和強大的型別安全檢查功能,迅速成為開發者的首選工具。本文將探討FastAPI的核心特性、實務應用及其在現代Web開發中的重要地位。
為何選擇FastAPI?
在眾多Python Web框架中,FastAPI憑藉其現代化的設計理念和強大的功能脫穎而出。相較於傳統框架如Flask和Django,FastAPI在以下方面展現出獨特優勢:
- 高效能表現:FastAPI根據標準的Python型別提示,利用
async/await語法實作非同步處理,大幅提升了系統效能。 - 自動化檔案生成:透過與OpenAPI的無縫整合,FastAPI能夠自動生成互動式API檔案,極大地簡化了開發與測試流程。
- 嚴格的型別檢查:利用Python 3.7+的型別提示功能,FastAPI提供了強大的資料驗證和自動檔案生成功能,減少了手動除錯的時間。
FastAPI的核心元件
1. 資料層設計
在FastAPI應用中,資料層扮演著至關重要的角色。開發者可以利用如SQLAlchemy或SQLModel等ORM工具實作資料函式庫操作。例如,使用SQLModel建立資料模型:
from sqlmodel import SQLModel, Field
class Hero(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
name: str
secret_name: str
age: Optional[int] = None
內容解密:
SQLModel用於定義資料模型,結合了Pydantic的資料驗證功能和SQLAlchemy的資料函式庫操作能力。Field函式用於定義欄位屬性,如主鍵或預設值。- 這種宣告方式不僅簡化了資料函式庫操作,還確保了資料的一致性和安全性。
2. 身份驗證與授權機制
FastAPI提供了靈活的身份驗證機制,支援多種驗證方式,如OAuth2和JWT。例如,實作一個簡單的JWT驗證:
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
# 驗證token並取得使用者資訊
if token != "fake-jwt-token":
raise HTTPException(status_code=401, detail="Invalid authentication credentials")
return {"username": "user"}
內容解密:
OAuth2PasswordBearer用於定義OAuth2的密碼模式。Depends機制實作了依賴注入,用於處理驗證邏輯。- 這種設計使得身份驗證邏輯清晰可維護,同時具備高度的可擴充性。
測試策略與實作
測試是確保FastAPI應用穩定的關鍵。開發者可以採用多層次的測試策略:
- 單元測試:針對個別元件進行測試,例如Service層邏輯。
- 整合測試:驗證不同元件之間的互動是否正常。
- 端對端測試:模擬真實使用者場景,全面檢查系統功能。
例如,使用Pytest進行單元測試:
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"msg": "Hello World"}
內容解密:
TestClient用於模擬HTTP請求,測試API端點的功能是否正確。- 透過斷言檢查回應狀態碼和內容,確保符合預期結果。
生產環境佈署最佳實踐
將FastAPI應用佈署到生產環境需要考慮多個因素,包括效能最佳化、安全性和可擴充性。以下是一些關鍵步驟:
- 使用Docker容器化:將應用及其依賴封裝成Docker映像,簡化佈署流程。
- 組態HTTPS加密傳輸:使用SSL/TLS憑證確保資料傳輸的安全性。
- 採用Kubernetes進行容器協調:實作自動化的擴充和負載平衡。
為什麼選擇FastAPI?
FastAPI是一個現代化的Python網頁框架,它結合了高效能、易用性和豐富的功能。作者在書中分享了他使用FastAPI開發生物醫學API網站的經驗,以及如何與團隊一起重寫舊的核心API。結果證明,FastAPI不僅提高了開發效率,還減少了錯誤。
FastAPI的優勢
- 高效能:FastAPI根據標準的Python型別提示,使用現代化的Python語法,並且與async/await語法無縫整合,使其能夠處理高並發請求。
- 易用性:FastAPI提供了簡潔直觀的API設計,使得開發者能夠快速上手並構建穩健的應用程式。
- 豐富的功能:FastAPI內建支援資料驗證、序列化、互動式檔案生成等功能,大大簡化了開發流程。
本文的目的
本文旨在幫助讀者快速掌握FastAPI的核心概念和最佳實踐。作者透過實際案例和經驗分享,引導讀者瞭解如何使用FastAPI構建高效、穩健的網頁應用程式。
本文的結構
- 第一部分:介紹網頁和Python的發展趨勢,包括服務和API、並發處理、分層架構等主題。
- 第二部分:對FastAPI進行高層次的介紹,展示其如何解決第一部分提出的問題。
- 第三部分:探討FastAPI的工具箱,包括在生產開發過程中學到的技巧和最佳實踐。
- 第四部分:提供一系列使用FastAPI構建的網頁範例,使用共同的資料來源——虛構生物,以展示如何將FastAPI應用於不同的場景。
排版規範
本文採用以下排版規範:
- 斜體字:表示新術語、網址、電子郵件地址、檔案名稱和副檔名。
固定寬度:用於程式列表,以及在段落中參照程式元素,如變數或函式名稱、資料函式庫、資料型別、環境變數、陳述式和關鍵字。固定寬度粗體:顯示使用者應逐字輸入的命令或其他文字。固定寬度斜體:顯示應由使用者提供的數值或由上下文決定的數值所取代的文字。
結語
本文旨在幫助讀者掌握FastAPI的核心概念和最佳實踐,並透過實際案例和經驗分享,引導讀者瞭解如何使用FastAPI構建高效、穩健的網頁應用程式。希望讀者能夠從中獲得有價值的知識,並成為更具生產力的網頁開發者。
現代網路
網路就像我所設想的那樣,我們還沒有真正看到它。未來遠比過去更為廣闊。 — Tim Berners-Lee
預覽
曾經,網路是小而簡單的。開發者們樂於將 PHP、HTML 和 MySQL 的呼叫混合在單一檔案中,並自豪地讓所有人檢視他們的網站。但隨著時間的推移,網路發展到無數頁面,早期的遊樂場變成了大型的綜合娛樂場。
在本章中,我將指出一些與現代網路越來越相關的領域:
- 服務和 API
- 平行性
- 層級
- 資料
下一章將介紹 Python 在這些領域的提供。之後,我們將探討 FastAPI 網路框架及其提供的功能。
服務和 API
網路是一個偉大的連線結構。儘管許多活動仍然發生在內容端,如 HTML、JavaScript、圖片等,但越來越強調的是連線這些內容的應用程式介面(API)。
通常,網路服務處理底層的資料庫存取和中層的商業邏輯(通常統稱為後端),而 JavaScript 或行動應用程式則提供豐富的前端(互動式使用者介面)。這兩個世界變得越來越複雜和不同,通常需要開發者專注於其中一個。因此,要成為一名全端開發者比以往更具挑戰性。
這兩個世界使用 API 進行溝通。在現代網路中,API 的設計與網站本身的設計一樣重要。API 是一種契約,類別似於資料函式庫架構。定義和修改 API 現在是一項重要的工作。
API 的種類別
每個 API 都定義了以下內容:
- 協定:控制結構
- 格式:內容結構
隨著技術從獨立機器發展到多工系統,再到網路伺服器,多種 API 方法應運而生。您可能會遇到其中一種或多種,因此在探討 HTTP 及其相關技術之前,以下是簡要的總結:
- 在網路出現之前,API 通常意味著非常緊密的連線,就像呼叫同一語言中的函式庫一樣,例如在數學函式庫中計算平方根。
- 遠端程式呼叫(RPC)被發明用來呼叫其他程式中的函式,無論是在同一台機器上還是在其他機器上,就像它們在呼叫應用程式中一樣。目前一個流行的例子是 gRPC。
- 訊息傳遞在程式之間的小型資料區塊中進行傳遞。訊息可能是動詞般的命令,也可能只是表示名詞般的事件。目前流行的訊息解決方案,包括 Apache Kafka、RabbitMQ、NATS 和 ZeroMQ,差異很大,從工具包到完整的伺服器。通訊可以遵循不同的模式:
- 請求-回應:一對一,就像網頁瀏覽器呼叫網頁伺服器一樣。
- 發布-訂閱(pub-sub):發布者發出訊息,訂閱者根據訊息中的某些資料(如主題)對其進行處理。
- 佇列:與 pub-sub 類別似,但只有一個訂閱者池中的成員抓取訊息並對其進行處理。
這些模式中的任何一種都可以與網路服務一起使用,例如執行緩慢的後端任務,如傳送電子郵件或建立縮圖。
HTTP
Berners-Lee 為他的全球資訊網提出了三個組成部分:
- HTML:用於顯示資料的語言
- HTTP:客戶端-伺服器協定
- URL:網路資源的定址方案
儘管這些看起來很明顯,但它們卻是一個非常有用的組合。隨著網路的發展,人們進行了實驗,一些想法,如 IMG 標籤,在達爾文式的競爭中倖存下來。隨著需求變得更加明確,人們開始認真地定義標準。
REST(ful)
Roy Fielding 的博士論文中的一章定義了表示狀態轉移(REST)——一種用於 HTTP 使用的架構風格。雖然經常被參照,但它基本上被誤解了。
一種大致分享的適應方式已經演變並主導了現代網路。它被稱為 RESTful,具有以下特徵:
- 使用 HTTP 和客戶端-伺服器協定
- 無狀態(每個連線都是獨立的)
- 可快取
- 根據資源
資源是您可以區分並對其執行操作的資料。網路服務為其想要公開的每個功能提供了一個端點——一個獨特的 URL 和 HTTP 動詞(動作)。端點也被稱為路由,因為它將 URL 路由到一個函式。
資料函式庫使用者熟悉 CRUD 縮寫詞程式:建立、讀取、更新、刪除。HTTP 動詞相當於 CRUD:
- POST:建立(寫入)
- PUT:完全修改(替換)
- PATCH:部分修改(更新)
- GET:讀取(檢索)
- DELETE:刪除
客戶端向 RESTful 端點傳送請求,資料位於 HTTP 訊息的以下區域之一:
- 標頭
- URL 字串
- 查詢引數
- 本體值
反過來,HTTP 回應傳回以下內容:
- 一個整數狀態碼,表示如下:
- 100s:資訊,請繼續
- 200s:成功
- 300s:重新導向
- 400s:客戶端錯誤
- 500s:伺服器錯誤
- 各種標頭
- 一個本體,可能為空、單一或分塊(在連續的部分中)
至少有一個狀態碼是一個彩蛋:418(我是一個茶壺),如果被要求沖泡咖啡,則應由連線到網際網路的茶壺傳回。
您將在許多網站和書籍中找到有關 RESTful API 設計的有用經驗法則。本文將在途中分享一些。
JSON 和 API 資料格式
前端應用程式可以與後端網路服務交換純 ASCII 文字,但如何表達像事物清單這樣的資料結構?
就在我們真正需要它的時候,JavaScript 物件表示法(JSON)出現了——另一個簡單的想法,解決了一個重要的問題,事後看來似乎很明顯。儘管 J 代表 JavaScript,但語法看起來也非常像 Python。
JSON 在很大程度上取代了舊的嘗試,如 XML 和 SOAP。在本文的其餘部分,您將看到 JSON 是預設的網路服務輸入和輸出格式。
JSON:API
RESTful 設計和 JSON 資料格式的組合現在很常見。但是仍然存在一些模糊性和爭論。最近的 JSON:API 提議旨在收緊規格。本文將使用寬鬆的 RESTful 方法。
import json
# 定義一個簡單的 Python 資料結構
data = {
"name": "John Doe",
"age": 30,
"city": "New York"
}
# 將 Python 資料結構轉換為 JSON 字串
json_data = json.dumps(data, indent=4)
print("JSON 資料:")
print(json_data)
# 將 JSON 字串轉換回 Python 資料結構
loaded_data = json.loads(json_data)
print("\n載入的 Python 資料:")
print(loaded_data)
程式碼解密:
此範例程式碼展示瞭如何使用 Python 的 json 模組在 Python 資料結構和 JSON 字串之間進行轉換。首先,我們定義了一個簡單的 Python 字典 data,其中包含一些個人資料。然後,我們使用 json.dumps() 將其轉換為 JSON 字串,並列印出來。接著,我們使用 json.loads() 將 JSON 字串載入回 Python 資料結構,並再次列印出來,以驗證轉換過程是否正確無誤。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 程式碼解密:
rectangle "json.dumps()" as n1
rectangle "json.loads()" as n2
n1 --> n2
@enduml圖表翻譯:
此圖表展示了 Python 資料結構與 JSON 字串之間的轉換過程。首先,Python 資料透過 json.dumps() 方法被序列化為 JSON 字串。然後,這個 JSON 字串可以透過 json.loads() 方法被反序列化回 Python 資料結構。這種轉換使得 Python 程式能夠與使用 JSON 的系統(如許多網路服務)進行互動。