# FastAPI APIRoute() 應用實作 - *Route in Large System* ###### tags: `backend` Copyright 2021, [月下麒麟](https://hackmd.io/@YMont/note-catalog) --- ## Target >查爾斯成立的公司已邁入第10年,隨著公司組織的擴張 >不得不想個辦法,為賺錢部門裁切出去成為一個獨立的公司 >否則,這營運、經營起來的難度,已超出查爾斯當年的預期 >這令他白髮掉滿地... ==今天會說明關於URL與Route的應用== (咦 Route是什麼!?) ## Concept 舉個實例[顏氏牧場](https://yenpasture.com/pasture1/scene.php)來說 (單純覺得它網頁做得很漂亮 作為引用,沒有業配也沒有工商XD) 牧場主頁,裡面依序有五個分頁(理念、食宿、預約、風情、前往) ``` https://yenpasture.com/pasture1 ``` ![](https://i.imgur.com/E2zYiu8.png) <br> 牧場理念 ``` https://yenpasture.com/pasture1/about.php ``` ![](https://i.imgur.com/YPEYGfF.png) <br> 露營食宿 ``` https://yenpasture.com/pasture1/camp.php ``` ![](https://i.imgur.com/xuabZ5X.png) <br> 其他分頁以此類推,就不繼續列舉 是否有發現一個規律呢 **觀察1** 我再把這幾個URL放在一起 觀察看看 ``` https://yenpasture.com/pasture1 https://yenpasture.com/pasture1/about.php https://yenpasture.com/pasture1/camp.php https://yenpasture.com/pasture1/scene.php https://yenpasture.com/pasture1/map.php ``` 在主結構pasture1下,有四個分頁,依序為about, camp, scene, map 對應到UI的畫面,當然使用者就能一目了然這幾個分頁的功能 再對應到後端的開發、管理,做好切分分類的工作後,未來無論是修改或是擴增,絕對都會很方便操作。 **觀察2** 如果你具備強烈的好奇心,你可能會跟我一樣想**有pasture1**,那是不是也會有**pasture2呢** 沒錯,筆者當時也是這樣思考的 ``` https://www.yenpasture.com/pasture2 #這個會出現404 not found https://www.yenpasture.com/pasture2/ #這個會redirect Website Expired ``` 但遺憾的是開發者並沒有這樣想 ~~可惡 猜錯了~~ 不過,*這樣觀察會發現,它網頁原本應該還是架在pasture2的XD* <br> **觀察3** 推測它的2應該有變更過啦XD 或許跟他的中文命名有相關,但是1也沒有再回頭重新修改了(茶~) ![](https://i.imgur.com/7bwXoS8.png) ``` https://www.yenpasture2.com/workshop # 牧場2在這裡 ``` <br> ```typescript= |--yenpasture/ |--yenpasture/pasture1/ | |--yenpasture/pasture1/about.php | |--yenpasture/pasture1/camp.php | |--yenpasture/pasture1/booking.php | |--yenpasture/pasture1/scene.php | |--yenpasture/pasture1/map.php | |--yenpasture2/pasture/ | |--yenpasture2/pasture/events | |--yenpasture2/pasture/shop | |--yenpasture2/pasture/photography | |--yenpasture2/pasture/picnic | |--yenpasture2/pasture/party | |--yenpasture2/pasture/2021-marketing | |--yenpasture2/pasture/about ``` URL就不多加解釋啦 至於Route在中文上會稱作**路由**,可以把它理解成一種URL切換的過程(路徑) Route是後端再切分邏輯做使用的 ==白話來說,當你網頁畫面**點擊顏氏牧場1的關於**, 故後端需要把yenpasture/pasture1/about這段URL, 做**切換**到這個位置(顏氏牧場1的關於)== --- ## Implement 廢話不多說,讓我們進行實作吧! ### Directory Achitecture ```typescript= |--app |--__init__.py |--main.py | |--\route1 | |--__init__.py | |--router1.py | |--\route2 |--__init__.py |--router2.py ``` ### URLs Achitecture 當然,你也可以把結構寫成這個樣子 ```typescript= |--127.0.0.1:8001/ |--127.0.0.1:8001/router |--127.0.0.1:8001/router/1 |--127.0.0.1:8001/router/2 ``` <br> 底下的架構,主要是想讓router1跟router2是平行關係的 至於上例好,還是下例好,就不在本次的討論範圍 主要==要展示如何使用FastAPI的 APIRouter的功能== ```typescript= |--127.0.0.1:8001/ |--127.0.0.1:8001/router1 |--127.0.0.1:8001/router2 ``` <br> 另一精神是為了==解決資料夾分層結構==的問題 當撰寫的系統日趨龐大,勢必就會遇到程式分類的問題 那為了避免Python在import來 import去的,導致產生import loop與route錯誤的問題 故就來使用這方便的工具吧 ### Code-router1 ```python= # router1.py from fastapi import FastAPI, APIRouter, HTTPException router = APIRouter() # point! @router.get("/router1") def router1() -> dict: return {"msg":"Hello Router1"} ``` ### Code-router2 ```python= # router2.py from fastapi import FastAPI, APIRouter, HTTPException router = APIRouter() # point! @router.get("/router2") def router1() -> dict: return {"msg":"Hello Router2"} ``` ### Code-main ```python= from fastapi import FastAPI, APIRouter, HTTPException # 將route1、2資料夾內的router1、2 python檔引入 from route1 import router1 from route2 import router2 app = FastAPI() # 以app作為FastAPI實例 api_router = APIRouter() # 以api_router作為APIRouter實例,本次重點! api_router.include_router(router1.router) # 把router1檔案裡的路由結合進api_router api_router.include_router(router2.router) # 把router2檔案裡的路由結合進api_router @api_router.get("/") def root() -> dict: """ Root Get """ return {"msg":"Hello root"} app.include_router(api_router) # app實例將api_router的路由結合進去 if __name__ == "__main__": import uvicorn uvicorn.run(app, host="127.0.0.1", port=8001) ``` 執行後,成果如下 ![](https://i.imgur.com/RKfAjoy.png) ![](https://i.imgur.com/5otq1EL.png) <br> ![](https://i.imgur.com/PFaXptZ.png) ![](https://i.imgur.com/7aytBkC.png) <br> ![](https://i.imgur.com/twXgxTM.png) ![](https://i.imgur.com/1HoC7tY.png) <br> ## Reference [FastAPI Bigger Applications - Multiple Files¶](https://fastapi.tiangolo.com/tutorial/bigger-applications/) ## Supplement **1** 這個功能就類似於flask的**Blueprints** >If you come from Flask, this would be the equivalent of Flask's Blueprints. **2** 你可能會擔心切換路由,會產生網路效能的問題,進而造成delay >You don't have to worry about performance when including routers. This will take microseconds and will only happen at startup. So it won't affect performance. ⚡ ## Summary 滿強大的一個功能,使用起來也很方便操作 希望有幫助到你的學習