목차
반응형
1. 개념
1.1. 설명
- 객체 생성 로직을 캡슐화
- 팩토리(Factory) 역할을 하는 메서드나 클래스를 통해 객체를 생성
- 객체 생성의 책임을 별도의 팩토리 클래스 또는 메서드에 위임하여, 객체 생성 로직을 단순화하고 클라이언트 코드와의 결합도를 낮추는 것
1.2. 사용 목적
- 객체 생성 방식이 변경되더라도 클라이언트 코드에 영향을 최소화
- 객체 생성 과정의 복잡성을 숨기고 단순화.
1.3. 언제 사용하는가?
- 앱 초기화
- 구성 요소 관리
2. FastAPI 활용 예시
2.1. 앱 초기화 예시
다음과 같은 구조로 코드 예시를 정리한다. (여기서 app.py가 핵심이다.)
project/
├── app.py # 앱 초기화 및 팩토리 메서드 정의
├── main.py # 애플리케이션 실행 진입점
├── config.py # 설정 관리
├── routers/ # 라우터 모듈화
│ ├── user_router.py
│ └── item_router.py
└── models/ # 데이터베이스 모델 정의 (예시)
└── base.py
app.py
# app.py
from fastapi import FastAPI
from config import get_settings
from routers.user_router import user_router
from routers.item_router import item_router
def create_app() -> FastAPI:
"""팩토리 패턴을 활용한 FastAPI 앱 초기화"""
app = FastAPI()
_register_routers(app) # 라우터 등록
_register_event_handlers(app) # 이벤트 핸들러 등록
return app
def _register_routers(app: FastAPI):
"""라우터를 FastAPI 앱에 등록"""
app.include_router(user_router, prefix="/users", tags=["Users"])
app.include_router(item_router, prefix="/items", tags=["Items"])
def _register_event_handlers(app: FastAPI):
"""이벤트 핸들러 등록"""
@app.on_event("startup")
async def on_startup():
settings = get_settings()
print(f"Starting application in {settings.env} environment...")
@app.on_event("shutdown")
async def on_shutdown():
print("Shutting down application...")
main.py
from app import create_app
app = create_app()
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
코드 설명
1. app.py 의 create_app() 함수에서 객체 생성 로직을 캡슐화 한다.
2. main.py 에서 create_app()를 실행해 객체를 생성해 준다.
2.2. 구성 요소 초기화
다음 예시는 구성요소들을 초기화 하는 것이다.
코드 구조는 다음과 같다.
project/
├── app.py # FastAPI 앱과 구성 요소 초기화
├── main.py # 앱 실행 엔트리 포인트
├── config.py # 설정 관리
├── components/ # 구성 요소 관리
│ ├── database.py # 데이터베이스 초기화
│ └── redis.py # Redis 클라이언트 초기화
└── routers/ # 라우터 관리
└── example_router.py
app.py
아래 코드에서는 데이터베이스, Redis 를 초기화 하고 있다.
# app.py
from fastapi import FastAPI
from components.database import init_db
from components.redis import init_redis
from config import get_settings
from routers.example_router import example_router
def create_app() -> FastAPI:
app = FastAPI()
app.include_router(example_router, prefix="/example", tags=["Example"])
# 구성 요소 초기화
_init_components(app)
return app
def _init_components(app: FastAPI):
"""구성 요소 초기화"""
settings = get_settings()
# 데이터베이스 초기화
app.state.db = init_db(settings.database_url)
# Redis 초기화
app.state.redis = init_redis(settings.redis_url)
# 이벤트 핸들러 등록 (시작/종료)
@app.on_event("startup")
async def startup():
print("Application is starting...")
await app.state.redis.ping() # Redis 연결 확인
@app.on_event("shutdown")
async def shutdown():
print("Application is shutting down...")
await app.state.redis.close() # Redis 연결 닫기
config.py: 환경별 설정 관리
from pydantic import BaseSettings
class Settings(BaseSettings):
database_url: str = "sqlite:///./test.db"
redis_url: str = "redis://localhost:6379"
class Config:
env_file = ".env"
def get_settings() -> Settings:
"""환경 설정 반환"""
return Settings()
components/database.py: 데이터베이스 초기화
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
def init_db(database_url: str):
"""데이터베이스 엔진과 세션 생성"""
engine = create_engine(database_url, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
return SessionLocal
components/redis.py: Redis 클라이언트 초기화
import aioredis
def init_redis(redis_url: str):
"""Redis 클라이언트 초기화"""
return aioredis.from_url(redis_url)
main.py
# main.py
from app import create_app
app = create_app()
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
위 코드에서 팩토리가 무엇인지 정리하자면 아래와 같다.
- get_settings: 환경 설정 객체를 생성해 반환
- init_db: 데이터베이스 엔진과 세션을 초기화해 객체를 반환
- init_redis : Redis 세션을 초기화해 객체를 반환
- create_app : FastAPI() 애플리케이션 객체를 생성해 반환
이처럼 각 구성 요소를 별도의 팩토리 함수로 관리하면 코드의 모듈화가 쉬워지고, 초기화 및 구성이 필요한 모든 요소를 명확하게 관리할 수 있다. 🎯
반응형
'Fastapi' 카테고리의 다른 글
[FastAPI] 디자인 패턴-라우터패턴(Router Pattern) (11-4) (0) | 2025.02.02 |
---|---|
[FastAPI] 디자인 패턴-미들웨어 패턴(Middleware Pattern) (11-3) (0) | 2025.01.27 |
[FastAPI] 디자인패턴-의존성 주입(Dependency Injection) (11-1) (0) | 2025.01.24 |
[FastAPI] 예외(Exception) 처리 방법 (10) (0) | 2025.01.19 |
[FastAPI] API의 Output (9) (1) | 2025.01.19 |