FastAPI 서버개발, 이벤트 문서 클래스와 라우트 변경

작성자: 조광형

날짜: 2024년 11월 26일

1. FastAPI란?

FastAPI는 Python의 비동기 웹 프레임워크로, API 서버를 개발하는 데 최적화되어 있습니다. Python의 타입 힌트를 활용하여 강력한 데이터 검증 및 문서화 기능을 제공합니다. FastAPI는 스타트업에서 대규모 애플리케이션에 이르기까지 다양한 프로젝트에 적합하며, OpenAPI와 JSON Schema를 지원하여 자동으로 API 문서를 생성합니다. 이러한 특징 덕분에 FastAPI는 효율적이고 명확한 API 서버 개발을 가능하게 합니다.

2. FastAPI 설치

FastAPI는 pip를 사용하여 간편하게 설치할 수 있습니다. 프로젝트를 시작하기 위해 가상 환경을 설정하고 FastAPI와 Uvicorn(ASGI 서버)을 설치하는 방법은 다음과 같습니다.

bash
# 가상 환경 설정
python -m venv venv
source venv/bin/activate  # 리눅스/Mac
venv\Scripts\activate  # 윈도우

# FastAPI와 Uvicorn 설치
pip install fastapi uvicorn
            

이제 FastAPI를 사용할 준비가 되었습니다.

3. 이벤트 문서 클래스란?

이벤트 문서 클래스는 특정 이벤트에 대한 정보를 담고 있는 데이터 모델을 정의합니다. FastAPI는 Pydantic을 사용하여 데이터 모델을 정의하고 검증합니다. 예를 들어, 이벤트의 제목, 설명, 발생 일시 등을 포함하는 이벤트 모델을 만들어 보겠습니다.

python
from pydantic import BaseModel
from datetime import datetime

class Event(BaseModel):
    title: str
    description: str
    event_date: datetime
    location: str
            

이벤트 모델은 FastAPI의 요청 및 응답 본문에서 사용할 수 있습니다. 이 모델을 활용하면 API에서 수신되는 데이터의 유효성을 검사하고, 자동으로 문서화할 수 있습니다.

4. FastAPI 라우트 설정

라우트는 HTTP 요청에 대한 핸들러 역할을 합니다. FastAPI에서 라우트를 설정하려면 인스턴스를 생성한 후 데코레이터를 사용하여 경로를 정의합니다. 다음은 기본적인 FastAPI 애플리케이션 및 이벤트 모델을 활용한 API 라우트 설정 예제입니다.

python
from fastapi import FastAPI
from typing import List

app = FastAPI()

# 이벤트 리스트
events: List[Event] = []

# 이벤트 생성
@app.post("/events/", response_model=Event)
async def create_event(event: Event):
    events.append(event)
    return event

# 모든 이벤트 조회
@app.get("/events/", response_model=List[Event])
async def get_events():
    return events
            

위 코드는 이벤트를 생성하는 POST 요청과 모든 이벤트를 조회하는 GET 요청을 처리합니다.

5. 라우트 변경 및 추가 기능 구현

이제 기본적인 CRUD(Create, Read, Update, Delete) 기능을 갖춘 이벤트 API를 확장해 보겠습니다. 여기서는 이벤트 업데이트 및 삭제 기능을 추가하는 방법을 설명하겠습니다.

python
from fastapi import HTTPException

# 이벤트 업데이트
@app.put("/events/{event_id}", response_model=Event)
async def update_event(event_id: int, updated_event: Event):
    if event_id < 0 or event_id >= len(events):
        raise HTTPException(status_code=404, detail="Event not found")
    events[event_id] = updated_event
    return updated_event

# 이벤트 삭제
@app.delete("/events/{event_id}", response_model=Event)
async def delete_event(event_id: int):
    if event_id < 0 or event_id >= len(events):
        raise HTTPException(status_code=404, detail="Event not found")
    deleted_event = events.pop(event_id)
    return deleted_event
            

이 코드는 이벤트를 업데이트하는 PUT 요청과 삭제하는 DELETE 요청을 처리합니다. 각각의 요청은 이벤트의 ID를 경로 매개변수로 사용하여 특정 이벤트를 관리할 수 있도록 합니다.

6. 데이터베이스와의 통합

FastAPI 애플리케이션은 데이터베이스와 쉽게 통합할 수 있습니다. SQLAlchemy를 사용하여 데이터베이스와의 상호작용을 구현하는 방법을 살펴보겠습니다. 다음은 SQLite 데이터베이스에 연결하고 이벤트 모델을 저장하고 가져오는 방법의 예시입니다.

python
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

Base = declarative_base()

class EventORM(Base):
    __tablename__ = "events"
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String)
    description = Column(String)
    event_date = Column(DateTime)
    location = Column(String)

# SQLite 데이터베이스 연결
engine = create_engine("sqlite:///./events.db")
Base.metadata.create_all(bind=engine)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# FastAPI 라우트에서 사용
@app.post("/events/", response_model=Event)
async def create_event(event: Event):
    db = SessionLocal()
    db_event = EventORM(**event.dict())
    db.add(db_event)
    db.commit()
    db.refresh(db_event)
    db.close()
    return db_event
            

위의 코드는 SQLite 데이터베이스에 이벤트 데이터를 저장하는 방법을 보여줍니다. SQLAlchemy를 사용하여 데이터베이스 연결과 ORM(Object-Relational Mapping) 설정을 하였습니다.

7. 비동기 작업 및 성능 최적화

FastAPI는 비동기 작업을 쉽게 처리할 수 있도록 설계되었습니다. 데이터베이스 작업을 비동기로 처리하면, 성능을 더욱 향상시킬 수 있습니다. SQLAlchemy의 비동기 기능을 사용하는 방법은 다음과 같습니다.

python
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
DATABASE_URL = "sqlite+aiosqlite:///./events.db"

# 비동기 데이터베이스 엔진
async_engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = sessionmaker(async_engine, expire_on_commit=False, class_=AsyncSession)

@app.post("/events/", response_model=Event)
async def create_event(event: Event):
    async with AsyncSessionLocal() as session:
        db_event = EventORM(**event.dict())
        session.add(db_event)
        await session.commit()
        await session.refresh(db_event)
        return db_event
            

위의 코드는 비동기 세션을 사용하여 데이터베이스에 이벤트를 저장하는 방법을 보여줍니다. 성능 향상을 위해 비동기 작업을 활용할 수 있습니다.

8. API 문서화

FastAPI의 강력한 기능 중 하나는 자동으로 API 문서를 생성하는 것입니다. Swagger UI와 ReDoc을 기본적으로 지원하여, 작성한 API를 쉽게 문서화하고 테스트할 수 있습니다. FastAPI 애플리케이션을 실행한 후 http://localhost:8000/docs 또는 http://localhost:8000/redoc에 접속하여 문서를 확인할 수 있습니다.

9. 애플리케이션 실행하기

FastAPI 애플리케이션을 실행하려면, Uvicorn을 사용하여 서버를 실행할 수 있습니다. 아래 명령어를 통해 FastAPI 서버를 실행하세요.

bash
uvicorn main:app --reload
            

여기서 main은 Python 파일의 이름이며, app는 FastAPI 인스턴스의 이름입니다. --reload 옵션을 사용하면 코드 변경 시 자동으로 서버가 재시작됩니다.

10. 결론

이번 글에서는 FastAPI를 사용하여 이벤트 문서 클래스를 정의하고, 다양한 라우트를 설정하는 방법을 살펴보았습니다. 데이터베이스와의 통합 및 비동기 작업을 통해 더 나아가 성능 최적화 방법까지 알아보았습니다. FastAPI의 유용한 기능들을 활용하여 강력하고 유연한 API 서버를 구축할 수 있습니다.

이 글에서 소개한 내용이 FastAPI를 이해하고 활용하는 데 도움이 되었길 바랍니다. FastAPI의 다양한 기능을 실험하고, 여러분만의 흥미로운 프로젝트를 만들어보세요!