여지껏 우리는 API를 main.py에다가 작성하였다.
그런데 사실 모든 코드들을 main.py에다가 작성하는건 그리 좋지 못한 방법이다.
이번 시간에는 이 문제를 해결할 방법인 router에 대해 알아보겠다.
라우터란?
mini fastapi application이라고 생각하면 될 것 같다.
한마디로 여러 API를 다른 파일에다 작성하고 이걸 main app에다가 넣었다 끼웠다 하면된다.
프로젝트 폴더 구조
fastapi 공식문서에서는 다음과 같은 폴더 구조를 사용하는것을 권장하고 있다.
.
├── app
│ ├── __init__.py
│ ├── main.py
│ ├── dependencies.py
│ └── routers
│ │ ├── __init__.py
│ │ ├── items.py
│ │ └── users.py
│ └── internal
│ ├── __init__.py
│ └── admin.py
자 여기서 위에 라우터로 items.py와 users.py가 라우터로 들어가 있다.
이 둘은 item와 user에 관한 API를 담은 코드가 들어갈 것이다.
API 라우터의 간단한 예제
첫번째로 간단하게 user 라우터를 만들어보겠다.
from fastapi import APIRouter
router = APIRouter()
@router.get("/users/", tags=["users"])
async def read_users():
return [{"username": "Rick"}, {"username": "Morty"}]
@router.get("/users/me", tags=["users"])
async def read_user_me():
return {"username": "fakecurrentuser"}
@router.get("/users/{username}", tags=["users"])
async def read_user(username: str):
return {"username": username}
라우터의 사용법은 간단하다.
먼저 APIRouter를 선언한다
router = APIRouter()
나머지는 @app 데코레이션과 전부 똑같다.
path를 지정가능하고 디펜던시나 태그로 전부 지정 가능하다
@router.get("/users/", tags=["users"])
@router.get("/users/me", tags=["users"])
@router.get("/users/{username}", tags=["users"])
디펜던시
라우터와 관련없는 내용이나, 공식홈페이지 코드 공유를 위해 일단 여기다 작성한다. 내용을 이해하려면 그냥 넘어가는걸 추천
from fastapi import Header, HTTPException
async def get_token_header(x_token: str = Header(...)):
if x_token != "fake-super-secret-token":
raise HTTPException(status_code=400, detail="X-Token header invalid")
async def get_query_token(token: str):
if token != "jessica":
raise HTTPException(status_code=400, detail="No Jessica token provided")
좀더 복잡한 라우터 예제
이번에는 items.py를 만들어보자
from fastapi import APIRouter, Depends, HTTPException
from ..dependencies import get_token_header
router = APIRouter(
prefix="/items",
tags=["items"],
dependencies=[Depends(get_token_header)],
responses={404: {"description": "Not found"}},
)
fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}
@router.get("/")
async def read_items():
return fake_items_db
@router.get("/{item_id}")
async def read_item(item_id: str):
if item_id not in fake_items_db:
raise HTTPException(status_code=404, detail="Item not found")
return {"name": fake_items_db[item_id]["name"], "item_id": item_id}
@router.put(
"/{item_id}",
tags=["custom"],
responses={403: {"description": "Operation forbidden"}},
)
async def update_item(item_id: str):
if item_id != "plumbus":
raise HTTPException(
status_code=403, detail="You can only update the item: plumbus"
)
return {"item_id": item_id, "name": "The great Plumbus"}
아래와 같이 API 라우터를 선언할때 라우터에 global하게 prefix와 tags, 디펜던시가 선언가능하다.
prefix에 /items 라고 붙어있다. 그럼 라우터의 모든 path operation은 /items 로 시작한다.
router = APIRouter(
prefix="/items",
tags=["items"],
dependencies=[Depends(get_token_header)],
responses={404: {"description": "Not found"}},
)
가령 아래의 path 는 /items/{item_id} 가 된다.
@router.get("/{item_id}")
async def read_item(item_id: str):
그리고 아래처럼 global하게 tags와 response를 지정해줘도 또한번 추가로 tags와 reponse를 추가 가능하다.
@router.put(
"/{item_id}",
tags=["custom"],
responses={403: {"description": "Operation forbidden"}},
)
위 예제에서는 put의 태그는 ["items", "custom"]
두개가 되고 reponse도 404와 403을 가지게 된다.그리고 이것들도 docs에 두개다 반영된다.
라우터를 main FastAPI에 합치기
자 이제 app/main.py로 넘어오자
from fastapi import Depends, FastAPI
from .dependencies import get_query_token, get_token_header
from .internal import admin
from .routers import items, users
app = FastAPI(dependencies=[Depends(get_query_token)])
app.include_router(users.router)
app.include_router(items.router)
app.include_router(
admin.router,
prefix="/admin",
tags=["admin"],
dependencies=[Depends(get_token_header)],
responses={418: {"description": "I'm a teapot"}},
)
@app.get("/")
async def root():
return {"message": "Hello Bigger Applications!"}
라우터를 main fastapi에 합치는 방법은 include_rounter를 이용하는것이다
app.include_router(users.router)
app.include_router(items.router)
Custom 라우터 세팅
아래 예제는 admin.py에 대한 커스텀 세팅을 나타낸다.
app.include_router(
admin.router,
prefix="/admin",
tags=["admin"],
dependencies=[Depends(get_token_header)],
responses={418: {"description": "I'm a teapot"}},
)
먼저 컨셉부터 이해하자.
회사로부터 여러 프로젝트에 공용으로 쓰이는 admin.py를 당신이 받았다고 치자.
그런데 당신이 이걸 조금 수정해서 쓰려고 한다. 그런데 이 admin.py는 여러군데에서 쓰이는 파일이라 함부로 수정하기가 뭐하다
그럴 때 위 예제처럼 include_router 함수를 통해서 admin.py를 수정하지 않고 커스텀 세팅이 가능하다.
'Fast API > fastapi배우기' 카테고리의 다른 글
[FastAPI] 새롭게 추가된 Annotated (0) | 2023.12.11 |
---|---|
Fast API 배우기 23부 - SQL 데이터베이스 (3) | 2021.11.08 |
Fast API 배우기 22부 - CORS (0) | 2021.11.05 |
Fast API 배우기 21부 - Middleware (0) | 2021.11.05 |
Fast API 배우기 20부 - Security, authentication 인증 시스템 (2) | 2021.11.04 |
댓글