최근 웹 애플리케이션 개발에서 FastAPI는 파이썬 기반의 비동기 웹 프레임워크로 많은 인기를 얻고 있습니다. 이 글에서는 FastAPI 서버 개발 과정과 함께 Docker Compose를 활용하여 개발 환경을 설정하고 배포할 수 있는 방법에 대해 상세히 설명하겠습니다.
FastAPI 소개
FastAPI는 Python 3.6 이상에서 동작하는 현대적인 웹 프레임워크로, 특히 비동기 프로그래밍을 지원합니다. 그 주요 특징으로는 다음과 같은 것들이 있습니다:
- 고속: 페이로드와 까다로운 요청을 처리하는 데 최적화되어 있습니다.
- 직관적: Python 타입 힌트를 사용하여 코드의 가독성을 높입니다.
- 자동화된 문서화: Swagger UI 및 ReDoc을 통해 API 문서를 자동 생성합니다.
- 비동기 지원: Async/Await를 활용하여 더 많은 동시 요청을 처리할 수 있습니다.
FastAPI 서버 설정하기
FastAPI를 사용하기 위해서 먼저 환경을 설정해야 합니다. 아래의 예제에서는 FastAPI를 설치하고 간단한 API 서버를 만드는 과정을 보여줍니다.
1. 가상 환경 설정
FastAPI 프로젝트를 위한 가상 환경을 설정합니다.
python -m venv venv
source venv/bin/activate # 리눅스/macOS
venv\Scripts\activate # 윈도우
2. FastAPI 및 Uvicorn 설치
FastAPI와 ASGI 서버인 Uvicorn을 설치합니다.
pip install fastapi uvicorn
3. 간단한 API 코드 작성
아래와 같은 구조의 main.py
파일을 생성합니다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI!"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
4. 서버 실행
다음 명령어로 FastAPI 서버를 실행합니다.
uvicorn main:app --reload
서버가 실행되면 http://127.0.0.1:8000/docs에서 자동 생성된 Swagger UI를 통해 API를 테스트할 수 있습니다.
Docker Compose를 이용한 FastAPI 서버 배포
Docker Compose를 이용하면 여러 서비스를 쉽게 관리할 수 있습니다. FastAPI 서버와 데이터베이스(MySQL)를 함께 설정할 수 있습니다.
1. Docker 및 Docker Compose 설치
Docker와 Docker Compose가 설치되어 있어야 합니다. 리눅스에서는 다음 명령어로 설치할 수 있습니다:
sudo apt-get update
sudo apt-get install docker docker-compose
2. Dockerfile 작성
프로젝트 루트 디렉토리에 Dockerfile
을 생성합니다.
FROM python:3.9
# Set the working directory
WORKDIR /app
# Copy the requirements file
COPY requirements.txt .
# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code
COPY . .
# Expose the port the app runs on
EXPOSE 8000
# Command to run the application
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
3. requirements.txt 파일 생성
fastapi
uvicorn
mysql-connector-python
4. docker-compose.yml 파일 작성
다음으로 docker-compose.yml
파일을 작성합니다. 이 파일은 Docker Compose의 설정 파일입니다.
version: '3.8'
services:
app:
build: .
ports:
- "8000:8000"
depends_on:
- db
environment:
- DATABASE_URL=mysql://user:password@db:3306/db_name
db:
image: mysql:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_DATABASE: db_name
5. Docker Compose로 서비스 실행
아래 명령어로 Docker Compose를 실행하여 서비스들을 시작합니다.
docker-compose up --build
위 명령어를 실행하면 FastAPI 서버와 MySQL 데이터베이스가 컨테이너에서 실행됩니다. FastAPI는 http://localhost:8000
에서 접근 가능합니다.
FastAPI와 MySQL 연동하기
이제 FastAPI와 MySQL을 연동하여 데이터를 저장하고 가져올 수 있는 API를 작성하겠습니다.
1. 데이터베이스 모델 정의
SQLAlchemy를 사용하여 데이터베이스 모델을 정의합니다. 먼저 SQLAlchemy와 MySQL 커넥터를 설치합니다.
pip install sqlalchemy pymysql
이제 models.py
파일을 생성하고 아래와 같은 코드를 작성합니다.
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Item(Base):
__tablename__ = 'items'
id = Column(Integer, primary_key=True, index=True)
name = Column(String(50))
description = Column(String(255))
2. 데이터베이스 연결 설정
데이터베이스 연결을 위해 database.py
파일을 생성합니다.
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://user:password@db:3306/db_name"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
3. CRUD API 작성
FastAPI를 사용하여 CRUD(Create, Read, Update, Delete) API를 작성합니다. main.py
파일을 다음과 같이 업데이트합니다.
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from models import Item, Base
from database import SessionLocal, engine
# 데이터베이스 테이블 생성
Base.metadata.create_all(bind=engine)
app = FastAPI()
# 의존성 주입을 통해 세션 생성
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/items/", response_model=Item)
async def create_item(item: Item, db: Session = Depends(get_db)):
db.add(item)
db.commit()
db.refresh(item)
return item
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: int, db: Session = Depends(get_db)):
item = db.query(Item).filter(Item.id == item_id).first()
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
return item
@app.put("/items/{item_id}", response_model=Item)
async def update_item(item_id: int, item: Item, db: Session = Depends(get_db)):
db_item = db.query(Item).filter(Item.id == item_id).first()
if db_item is None:
raise HTTPException(status_code=404, detail="Item not found")
db_item.name = item.name
db_item.description = item.description
db.commit()
db.refresh(db_item)
return db_item
@app.delete("/items/{item_id}")
async def delete_item(item_id: int, db: Session = Depends(get_db)):
db_item = db.query(Item).filter(Item.id == item_id).first()
if db_item is None:
raise HTTPException(status_code=404, detail="Item not found")
db.delete(db_item)
db.commit()
return {"message": "Item deleted successfully"}
결론
이번 글에서는 FastAPI를 이용하여 간단한 API 서버를 구축하고, Docker Compose를 통해 개발 환경을 설정하는 방법을 배웠습니다. 또한 MySQL과의 연동을 통해 데이터를 관리하는 API를 작성하였습니다. FastAPI의 비동기 성능과 간결한 코드 작성을 통해 더 효율적인 웹 애플리케이션을 개발할 수 있습니다. Docker Compose를 이용하여 손쉽게 프로젝트를 배포하고 관리할 수 있어 개발자에게 유용한 도구입니다.
FastAPI와 Docker Compose를 이용한 개발은 현대적인 웹 개발을 추구하는 많은 인프라에서 필수적인 부분으로 자리잡고 있습니다. 앞으로 더 발전된 기능과 아키텍처를 활용하여 보다 혁신적인 애플리케이션을 만들어 나갈 수 있기를 기대합니다.