ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • FastAPI 시리즈 8화 - 의존성 주입 시스템(Depends) 실전 활용법
    언어 및 프레임워크/FastAPI 2025. 5. 9. 14:40
    728x90

    FastAPI의 Depends를 활용한 의존성 주입 시스템을 설명합니다. 공통 로직 재사용, 인증 처리, DB 연결 관리 등 실전 API 개발에서의 활용 패턴을 예제로 정리합니다.


    왜 의존성 주입(Dependency Injection)이 중요한가?

    전통적인 함수 호출 방식에서는 모든 기능을 하나의 엔드포인트 함수에서 직접 처리합니다.
    하지만 실제 서비스에서는 다음과 같은 공통 로직이 필요합니다:

    • 로그인 인증
    • DB 커넥션 핸들링
    • 공통 파라미터 처리
    • 권한 체크, API 사용량 제한

    이 로직들을 매번 복사해서 쓰는 것은 유지보수와 테스트 모두에게 지옥입니다.

    FastAPI의 Depends는 이런 문제를 한 줄로 해결합니다.


    1. Depends 기본 구조

    from fastapi import Depends, FastAPI
    
    app = FastAPI()
    
    def get_token_header():
        print("의존성 함수 실행됨")
        return "token123"
    
    @app.get("/items/", dependencies=[Depends(get_token_header)])
    def read_items():
        return {"message": "token 검증 완료"}
    
    • get_token_header()는 호출되지만 결과를 사용하지 않음
    • 주로 로그, 인증, 트래킹 목적으로 사용
    • Swagger 문서에선 표시되지 않지만 내부적으로 실행됨

    2. 값을 실제로 사용하는 방식

    def get_user_agent(user_agent: str = Header(...)):
        return user_agent
    
    @app.get("/user-agent")
    def show_agent(agent: str = Depends(get_user_agent)):
        return {"User-Agent": agent}
    
    • Depends(get_user_agent)를 통해 agent 값 자동 전달
    • 공통 파라미터 추출 및 재사용이 쉬워짐

    3. 인증 처리 예제 – 인증 토큰 검사

    from fastapi import HTTPException, status, Header
    
    def verify_token(token: str = Header(...)):
        if token != "secure-token":
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid Token"
            )
        return token
    
    @app.get("/secure-data")
    def secure_endpoint(token: str = Depends(verify_token)):
        return {"data": "비공개 데이터", "token": token}
    
    • verify_token()에서 인증 실패 시 HTTP 예외 발생
    • 성공 시 토큰 값이 라우터 함수에 전달됨

    4. 의존성 계층 구조 (Nested Dependencies)

    def get_db():
        print("DB 연결 생성")
        return "db_conn"
    
    def get_user(db=Depends(get_db)):
        print(f"{db}에서 사용자 조회")
        return {"username": "alice"}
    
    @app.get("/profile")
    def profile(user=Depends(get_user)):
        return user
    
    • get_user()는 get_db()에 의존
    • FastAPI는 자동으로 계층 구조를 추론하고 순차 실행함
    • 복잡한 로직도 모듈화하고 테스트 가능

    5. 클래스 기반 의존성 주입

    class CommonQueryParams:
        def __init__(self, q: str = "", page: int = 1):
            self.q = q
            self.page = page
    
    @app.get("/search")
    def search(params: CommonQueryParams = Depends()):
        return {"query": params.q, "page": params.page}
    
    • 의존성 객체를 클래스로 선언하면 상태 + 파라미터 처리를 함께 다룰 수 있음
    • 내부 로직을 메서드화하면 훨씬 강력한 서비스 객체 패턴 구현 가능

    6. 고급 기능 – dependency_overrides

    테스트 환경에서 실제 인증 대신 mock 함수를 주입할 수도 있습니다.

    def override_token():
        return "test-token"
    
    app.dependency_overrides[verify_token] = override_token
    
    • 테스트 환경에서만 인증 우회 처리
    • 유닛 테스트, 통합 테스트 시 매우 유용

    정리 – Depends는 FastAPI의 확장성과 품질의 핵심 축

    기능 활용 예

    공통 인증 처리 로그인 토큰 검증
    파라미터 재사용 헤더, 쿠키, 쿼리 스트링 추출
    로깅 및 감사 미들웨어 대체용
    DB 관리 커넥션 생성 및 반환 구조화
    테스트 유연성 mock 주입을 통한 테스트

    FastAPI에서 Depends는 단순 헬퍼가 아닌 아키텍처 설계 도구입니다.
    적절히만 사용한다면, 유지보수 가능한 API 백엔드를 구성하는 데 큰 힘이 됩니다.


    다음 글 예고

    FastAPI 시리즈 9화 - Background Tasks: 비동기 작업을 우아하게 처리하는 방법
    에서는 사용자의 요청과 동시에 백그라운드에서 실행할 수 있는 작업(알림 전송, 로그 기록 등)을
    어떻게 BackgroundTasks로 처리할 수 있는지를 다룹니다.

    728x90
Designed by Tistory.