FastAPI는 파이썬으로 작성된 현대적인 웹 프레임워크로, APIs를 빠르게 구축하고 문서화하는 데 있어 효율성을 제공합니다. 이 글에서는 FastAPI를 사용하여 백엔드 서버를 개발하는 방법과 함께 비동기 MySQL 데이터베이스 클라이언트인 aiomysql
의 설치 및 활용 방법에 대해 알아보겠습니다.
1. FastAPI 소개
FastAPI는 비동기 지원을 제공하며, Starlette 및 Pydantic을 기반으로 개발되었습니다. 이 프레임워크의 가장 큰 장점 중 하나는 데이터 검증 및 직렬화가 자동으로 이루어진다는 점입니다. 이는 개발자가 API를 개발하는 데 드는 시간을 크게 단축시켜 줍니다.
1.1 FastAPI의 주요 특징
- 비동기 지원: 매우 빠른 성능을 제공합니다.
- 자동 API Documentation: Swagger와 ReDoc을 통해 문서화가 자동으로 이루어집니다.
- 데이터 검증: Pydantic을 사용해 데이터 검증이 자동으로 이루어집니다.
- 의존성 주입: 쉽게 의존성을 설정하고 관리할 수 있습니다.
2. FastAPI 설치
FastAPI를 설치하기 위해서는 pip
를 사용하여 간단히 설치할 수 있습니다. 다음 명령어를 입력해 설치해 주세요:
pip install fastapi[all]
3. 기본 FastAPI 애플리케이션 만들기
FastAPI를 설치한 후, 기본 애플리케이션을 만들어 보겠습니다. 아래 예제 코드를 사용하여 main.py
라는 파일을 생성하고, 다음 코드를 붙여 넣습니다:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
위 코드는 기본 FastAPI 애플리케이션을 설정하는 코드로, 루트 endpoint에 GET 요청을 보내면 {"Hello": "World"}
라는 JSON 응답을 반환합니다. FastAPI 서버를 실행하려면 다음 명령어를 터미널에 입력하세요:
uvicorn main:app --reload
여기서 --reload
옵션은 코드 변경 시 서버를 자동으로 재시작해 주는 기능을 제공합니다. 서버가 실행되면 http://127.0.0.1:8000
주소에서 애플리케이션을 확인할 수 있습니다.
4. aiomysql 설치
이제 FastAPI 애플리케이션에 MySQL 데이터베이스를 연결하기 위해 aiomysql을 설치해 보겠습니다. aiomysql은 asyncio 기반의 MySQL 클라이언트로, 비동기적으로 MySQL과 상호작용할 수 있도록 해줍니다. aiomysql을 설치하기 위해 아래 명령어를 실행합니다:
pip install aiomysql
5. MySQL 데이터베이스 설정
설치가 완료되면 MySQL 서버를 준비해야 합니다. MySQL 서버를 실행하고, 아래 명령어를 사용하여 새 데이터베이스를 생성합니다:
CREATE DATABASE fastapi_db;
5.1 데이터베이스 테이블 생성
데이터베이스 안에 사용할 테이블을 생성해보겠습니다. 예를 들어 Users
라는 테이블을 생성하고, 사용자 정보를 저장해보겠습니다:
CREATE TABLE Users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
);
6. FastAPI와 aiomysql 통합
이제 FastAPI 애플리케이션에서 MySQL에 연결해 보겠습니다. 아래 코드는 FastAPI와 aiomysql을 사용하여 데이터베이스에 연결하고, 데이터를 삽입하고 조회하는 기본적인 API를 만드는 방법을 보여줍니다. 아래 코드를 main.py
에 추가하세요:
import aiomysql
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
app = FastAPI()
# MySQL 데이터베이스 연결 설정
DB_CONFIG = {
"host": "localhost",
"port": 3306,
"user": "your_username",
"password": "your_password",
"db": "fastapi_db"
}
# 데이터 모델 정의
class User(BaseModel):
name: str
email: str
# 비동기 함수: 데이터베이스 연결
async def get_db_connection():
conn = await aiomysql.connect(**DB_CONFIG)
return conn
# 사용자 추가
@app.post("/users/", response_model=User)
async def create_user(user: User):
conn = await get_db_connection()
async with conn.cursor() as cursor:
await cursor.execute("INSERT INTO Users (name, email) VALUES (%s, %s)", (user.name, user.email))
await conn.commit()
user_id = cursor.lastrowid
conn.close()
return {**user.dict(), "id": user_id}
# 사용자 목록 조회
@app.get("/users/", response_model=List[User])
async def read_users():
conn = await get_db_connection()
async with conn.cursor(aiomysql.DictCursor) as cursor:
await cursor.execute("SELECT * FROM Users")
result = await cursor.fetchall()
conn.close()
return result
6.1 API 테스트
이제 FastAPI 애플리케이션을 다시 실행한 후 API를 테스트해보세요. 예를 들어, 사용자 추가를 위해 다음과 같은 POST 요청을 보낼 수 있습니다:
curl -X POST "http://127.0.0.1:8000/users/" -H "Content-Type: application/json" -d "{\"name\": \"John\", \"email\": \"john@example.com\"}"
이 후, 사용자 목록 조회를 위해 다음 GET 요청을 보낼 수 있습니다:
curl -X GET "http://127.0.0.1:8000/users/"
7. 에러 핸들링
FastAPI에서의 에러 핸들링은 매우 간단합니다. 예를 들어, 사용자가 이메일을 중복해서 추가하려 할 경우를 처리하기 위한 기능을 추가해 보겠습니다:
from fastapi import HTTPException
@app.post("/users/", response_model=User)
async def create_user(user: User):
conn = await get_db_connection()
async with conn.cursor() as cursor:
await cursor.execute("SELECT * FROM Users WHERE email = %s", (user.email,))
existing_user = await cursor.fetchone()
if existing_user:
raise HTTPException(status_code=400, detail="Email already registered")
await cursor.execute("INSERT INTO Users (name, email) VALUES (%s, %s)", (user.name, user.email))
await conn.commit()
user_id = cursor.lastrowid
conn.close()
return {**user.dict(), "id": user_id}
8. 마치며
FastAPI는 간단하면서도 매우 강력한 웹 프레임워크입니다. aiomysql을 통해 비동기적으로 MySQL과 연결하는 방법을 배웠습니다. 이를 통해 데이터를 효율적으로 관리하고 빠른 성능을 구현할 수 있습니다. 추가적으로, FastAPI의 다양한 기능(예: 의존성 주입, 더 복잡한 데이터 모델 등)을 탐구하며 더 발전된 애플리케이션을 만들어보길 바랍니다.
감사합니다!