你寫了一支 Python 小程式,把待辦事項存在一個 list 裡,跑起來會印出清單,用起來很順手。後來朋友想在他的網頁上顯示這份清單,你要怎麼給他?把 .py 檔案傳過去,請他也裝一份 Python 環境執行?如果朋友用的是手機 App,或是另一個團隊的 Java 後端,這招根本行不通——他們不會裝 Python,也不該需要裝。
這正是 API 要解決的問題:讓不同程式、不同語言、不同裝置,都能透過一個共同的管道拿到你的資料,不必知道你背後是怎麼寫的。這篇文章就用 FastAPI 帶你實際寫出這樣一支 API,從安裝到看到自己的資料被瀏覽器讀到為止。
API 到底在幹嘛
把 API 想成餐廳裡的服務生會比較好理解。你(前端、或任何想要資料的程式)不會直接衝進廚房翻鍋子,而是跟服務生說「我要一份待辦清單」。服務生(API)把這個要求帶進廚房,廚房(後端邏輯、資料庫)把東西準備好,服務生再端出來給你。你完全不需要知道廚房裡發生了什麼事,只要知道怎麼點餐。
而 Web API 就是「用網址(URL)點餐」的服務生。一次完整的請求長這樣:
前端: GET http://127.0.0.1:8000/todos ← 我想要待辦清單
│
▼
FastAPI:找到對應的函式,執行,整理結果
│
▼
前端: ← 200 OK [{"id":1,"title":"學 FastAPI"}] (JSON 格式)回傳的資料格式通常是 JSON,長得很像 Python 的 dict/list,這也是為什麼待會你會發現 FastAPI 幾乎不用你手動轉換格式。
為什麼是 FastAPI
Python 寫 Web API 的框架不少,FastAPI 這幾年變成主流選擇,主要是三件事做得特別順手:
- 靠型別提示寫程式:函式參數寫上型別,FastAPI 就知道怎麼驗證、怎麼轉換,程式碼量比傳統寫法少很多。
- 自動產生文件:不用另外寫 API 文件,啟動伺服器後打開
/docs就有一頁可以直接點擊測試的互動文件(Swagger UI)。 - 自動資料驗證:搭配 Pydantic,前端傳錯格式的資料會被自動擋下並回傳清楚的錯誤訊息,不用自己寫一堆
if防呆。
環境準備
FastAPI 官方目前建議的安裝方式是裝 fastapi[standard],這會一次把 FastAPI 本體、ASGI 伺服器 uvicorn、還有常用的相依套件(例如處理表單、Email 驗證用的套件)一起裝好:
pip install "fastapi[standard]"如果你只想裝最精簡的組合(本文範例也只需要這樣),也可以分開裝:
pip install fastapi "uvicorn[standard]"fastapi 是框架本體,uvicorn 是負責「開伺服器、聽網路請求」的引擎(ASGI server)。用餐廳比喻的話,FastAPI 是菜單和廚師,uvicorn 則是把店真的開起來、接待客人的店面——所以等一下啟動程式時,我們是叫 uvicorn 去跑 FastAPI 寫好的內容,而不是直接執行 python main.py。
目前 FastAPI 最新版要求 Python 3.10 以上,執行 python --version 先確認一下你的版本沒問題。
寫出第一支 API
入門階段不需要複雜的專案結構,一個 main.py 就能跑出完整的 API。先建立最基本的 app 物件,並加上一個首頁路由:
from fastapi import FastAPI
app = FastAPI(title="待辦事項 API")
@app.get("/")
def root():
return {"message": "歡迎使用待辦事項 API"}這裡的 @app.get("/") 是一個裝飾器,意思是「有人用 GET 方法連到 / 這個網址時,執行下面這個函式」。括號裡的字串就是網址路徑,get 代表 HTTP 方法(讀資料用 get,之後新增資料會用到 post)。函式名稱你可以自己取,FastAPI 只在乎那個裝飾器。
存成 main.py 之後,在同一個資料夾用 uvicorn 啟動:
uvicorn main:app --reload加上真正的待辦清單
首頁只是打招呼,接下來讓它回傳真正的資料。先用一個 list 假裝是資料庫(之後要接真正的資料庫時,換掉這段就好,路由邏輯幾乎不用動),再加一個 /todos 路由把它回傳出去:
from fastapi import FastAPI
app = FastAPI(title="待辦事項 API")
# 先用一個 list 假裝是資料庫
todos = [
{"id": 1, "title": "學會 FastAPI", "done": False},
{"id": 2, "title": "寫出第一個 API", "done": True},
]
@app.get("/")
def root():
return {"message": "歡迎使用待辦事項 API"}
@app.get("/todos")
def list_todos():
return todos打開 /docs 看自動文件
寫到這裡,去瀏覽器連到 http://127.0.0.1:8000/docs,你會看到一頁自動生成、可以直接互動的 API 文件(Swagger UI),每個路由都能按「Try it out」當場測試,不用另外裝 Postman。這頁完全沒有另外寫一行文件,是 FastAPI 靠你寫的型別提示自動推斷出來的。另外還有一個版面不同的 /redoc 可以看。
[截圖建議:瀏覽器打開 /docs 後看到的 Swagger UI 互動文件畫面]
新手常踩的雷
- `uvicorn main:app` 對不起來:檔名要叫
main.py、物件要叫app,兩邊名字都要跟指令一致,改了檔名或變數名記得同步改指令。 - 忘記加 `--reload`:開發階段沒加,改完程式碼要手動 Ctrl+C 再重新啟動才會生效。
- 兩個路由用同一個路徑:例如兩個函式都掛
@app.get("/"),後面定義的會蓋掉前面那個,測試時容易搞不清楚是哪支在回應。 - 連錯網址:預設是
127.0.0.1:8000,不是 80 也不是別的埠號,複製貼上網址時容易漏看。
小結
一支 API 說穿了就是一個「用網址接受請求、回傳資料」的服務生,讓不同語言、不同裝置都能跟你的程式溝通,不必了解你背後是怎麼實作的。這篇文章做出的 GET /todos 只能讀取固定資料,還不能新增、修改或刪除,也還沒有資料驗證——這些正是接下來要補的功能:用路徑參數查單筆資料、用 Pydantic 模型驗證新增進來的待辦事項、做出完整的新增/修改/刪除。如果想把這支 API 一路做到能接資料庫、資料重啟也不會消失,可以參考「API 開發實戰」課程裡的 FastAPI 系列章節,從這支 main.py 繼續往下蓋。