한양과학기술고등학교

에듀테크 프로젝트 대시보드

의존성 주입 (Depends)

Depends 재사용 하위 의존성 Annotated

공통 로직(인증, 페이지네이션, DB 세션 등)을 함수로 추출하고 Depends 로 주입합니다. FastAPI 의 핵심 기능.

1. 함수 의존성

from typing import Annotated
from fastapi import Depends

def pagination(skip: int = 0, limit: int = 20) -> dict:
    return {"skip": skip, "limit": min(limit, 100)}

@app.get("/items")
def list_items(page: Annotated[dict, Depends(pagination)]):
    return items[page["skip"] : page["skip"] + page["limit"]]

의존성 함수의 파라미터(skip, limit)는 그대로 요청 쿼리 파라미터가 되고 /docs 에도 표시됩니다.

2. 타입 별칭으로 재사용

PaginationDep = Annotated[dict, Depends(pagination)]

@app.get("/items")
def list_items(page: PaginationDep): ...

@app.get("/users")
def list_users(page: PaginationDep): ...

3. 클래스 의존성

class QueryParams:
    def __init__(self, q: str | None = None, limit: int = 20):
        self.q = q
        self.limit = limit

@app.get("/search")
def search(params: Annotated[QueryParams, Depends()]):
    return {"q": params.q, "limit": params.limit}
# Depends() 안이 비면 타입 어노테이션을 그대로 사용

4. 하위 의존성 (체인)

def get_token(authorization: str = Header()) -> str:
    return authorization.removeprefix("Bearer ")

def get_current_user(token: Annotated[str, Depends(get_token)]) -> User:
    user = decode(token)
    if not user:
        raise HTTPException(401)
    return user

@app.get("/me")
def me(user: Annotated[User, Depends(get_current_user)]):
    return user

5. 반환값 없이 '검사만'

def verify_api_key(x_api_key: str = Header()):
    if x_api_key != settings.api_key:
        raise HTTPException(403, "invalid api key")

@app.get("/private", dependencies=[Depends(verify_api_key)])
def private():
    return {"ok": True}
# 반환값을 안 쓰므로 파라미터가 아닌 dependencies= 에 넣음

6. 캐싱

같은 요청 안에서 동일 의존성이 여러 번 참조되면 한 번만 실행되고 결과가 캐시됩니다. 끄려면 Depends(get_x, use_cache=False).

"마이그레이션 없는 스키마 변경은 사고의 시작이다"