在前面的文章中,我們都是盡可能使用最簡單的程式碼當作範例,不僅只有一個檔案 main.py
,一次也只有一個 API 在裡面。
然而,實際開發時,99% 的情況都會有好幾個 API,甚至往往都是幾十或幾百個。隨著 API 越來越多,開始需要管理,最後也需要一份文件來說明 API 的規格。因此,接下來我們會介紹 API 的管理,以及用 FastAPI 快速產生 API 文件的方法。
在開始重頭戲之前,先讓我們快速示範一下怎麼設定多個 API 在 main.py
內
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/ithome")
async def root():
return {"message": "ironman 2023"}
@app.get("/user")
async def root():
return {"message": "ck642509"}
如果還要更多 API,就只要再繼續往下加就好
管理 API 的第一個步驟,就是把 API 與主程式 main.py
分開
這邊就會使用到 FastAPI 的 APIRouter
(為一個 class),用法就跟 FastAPI
class 一樣,也就是說,使用方法就跟我們在 app
添加 router 一樣
這是原本在 app
加 router 的作法
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
這是在 APIRouter
加 router 的作法
from fastapi import APIRouter
router = APIRouter()
@router.get("/")
async def root():
return {"message": "Hello World"}
是不是幾乎一樣? XD
之後只要再用 include_router
把這個 APIRouter
接到 app
即可
# main.py
from fastapi import FastAPI
from api import router
app = FastAPI()
app.include_router(router)
# api.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/")
async def root():
return {"message": "Hello World"}
@router.get("/")
async def root():
return {"message": "Hello World"}
@router.get("/")
async def root():
return {"message": "Hello World"}
接下來,我們可以進一步依據路由 (通常同時也會是功能),把 api.py
內的 API 拆分開來。例如:讓 user.py
專門管理使用者相關的 API,data.py
專門處理數據相關的 API
最後,再把這些 API 相關檔案放進 routers
資料夾
# main.py
from fastapi import FastAPI
from routers.user import router as user_router
from routers.data import router as data_router
app = FastAPI()
app.include_router(user_router)
app.include_router(data_router)
# routers/user.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/user/{user_id}")
async def root(user_id):
return {"message": f"Hello user {user_id}"}
@router.post("/user")
async def root():
return {"message": "Hello World"}
# routers/data.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/data")
async def root():
return {"message": "Hello World"}
@router.post("/data")
async def root():
return {"message": "Hello World"}
此時的專案架構就會變成這樣
注意!
__init__.py
是必要檔案 (內容留空就好),這樣才能 import 到routers
內的檔案
依據路由分檔案還有另一個優點,就是可以統一管理路由的 prefix,這樣在每個檔案內就可以省去重複輸入相同的 prefix 的時間,也避免之後調整時有漏掉的 API 沒改到。
# main.py
from fastapi import FastAPI
from routers.user import router as user_router
from routers.data import router as data_router
app = FastAPI()
app.include_router(user_router, prefix="/user")
# routers/user.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/{user_id}")
async def root(user_id):
return {"message": f"Hello user {user_id}"}
@router.post("")
async def root():
return {"message": "Hello World"}
在更後期,可能會同時有多個 API 版本,需要在更前面加 /api/v1
之類的 prefix,就可以比照上方的做法,中間再多建立一層資料夾,甚至也可以把各個 API 檔案放進 endpoints
資料夾,架構就變成這樣
程式碼則是這樣
# main.py
from fastapi import FastAPI
from routers.api_v1.routers import router
app = FastAPI()
app.include_router(router, prefix="/api/v1")
# routers/routers.py
from fastapi import APIRouter
from routers.api_v1.endpoints.user import router as user_router
from routers.api_v1.endpoints.data import router as data_router
router = APIRouter()
router.include_router(user_router, prefix="/user")
router.include_router(data_router, prefix="/data")
# routers/api_v1/endpoints/user.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/{user_id}")
async def root(user_id):
return {"message": f"Hello user {user_id}"}
@router.post("")
async def root():
return {"message": "Hello World"}
讓我們來用昨天介紹的 Postman 測試一下
看來我們成功建立更複雜的 API 架構了~
隨著 API 越來越多、專案架構越來越複雜,擁有一份好的 API 文件就越來越重要。之後不論是交接給同事,或是與前端同事合作 API 的串接時,有一份好的 API 文件可以大幅減少溝通的成本。
先前有提過,FastAPI 是可以快速生成 API 文件的,現在來讓我們體驗一下到底有多快~
首先,打開瀏覽器,在網址輸入 http://127.0.0.1:8000/docs
後送出,接下來你就會看到這份文件
恭喜你,你建立好了 XD
如果不喜歡,也可以換一個,改成輸入 http://127.0.0.1:8000/redoc
不過,稍微研究一下你就會發現,裡面的內容還很簡單,應該還要再加上一些說明,甚至是範例,但這一部分進階設定,就讓我們明天再繼續介紹吧~
今天我們介紹了如何將 API 分門別類地放在不同檔案,再 import 進來,
include_router
加到主程式中的 app
明天會繼續介紹如何讓 API 文件更加完整的