Python 3.7+를 기반으로 API를 구축하기 위한 빠른 웹 프레임워크
이름 그대로 Fast(빠름)을 핵심 가치로 세운다.
Fast API는 핵심적인 파이썬 라이브러리, Starlette와 Pydantic에 기반한다.
각각 알아보자.
Starlette(ASGI)
ASGI : 비동기 처리
WSGI : 동기 처리
Pydantic
파이썬의 타입 힌트(Type Hints)를 활용하여 데이터의 유효성을 검사하고 설정을 관리하는 라이브러리
그냥 이 라이브러리가 타입 힌트 & 유효성 검사를 진행한다고 보면 되는 것 같다
Uvicorn
Fast API는 Uvicorn(ASGI) 위에서 동작한다 Uvicorn는 뭘까?
Uvicorn은 파이썬을 위해 만들어진 웹 서버 (비동기 처리가 특징이다)
자바는 톰캣, 파이썬은 Uvicorn 요런 느낌
/docs Swagger UI를 통해 API를 직접 호출하고 테스트해볼 수 있음./redoc 경정리된 API 명세를 확인할 수 있음./my_project
├── main.py # FastAPI 앱 인스턴스 생성 및 라우터 등록
├── /app
│ ├── __init__.py
│ ├── /routers # API 엔드포인트(경로) 정의
│ │ ├── __init__.py
│ │ └── users.py
│ │ └── items.py
│ ├── /models # 데이터베이스 ORM 모델 (예: SQLAlchemy)
│ │ ├── __init__.py
│ │ └── user.py
│ │ └── item.py
│ ├── /schemas # Pydantic 데이터 모델 (요청/응답 스키마)
│ │ ├── __init__.py
│ │ └── user.py
│ │ └── item.py
│ ├── /crud # 데이터베이스 CRUD(생성, 읽기, 수정, 삭제) 로직
│ │ ├── __init__.py
│ │ └── user.py
│ │ └── item.py
│ └── dependencies.py # 의존성 주입 함수
/your_project
├── main.py # ❶ FastAPI 앱의 시작점, 라우터 등록
│
├── /core # ❷ 프로젝트의 핵심 설정 (환경변수, 설정 값 등)
│ └── config.py
│
├── /db # ❸ 데이터베이스 연결 및 세션 관리
│ └── session.py
│
├── /models # ❹ 데이터베이스 테이블 구조 정의 (ORM 모델)
│ ├── user.py
│ └── item.py
│
├── /schemas # ❺ 데이터의 형태와 유효성 정의 (Pydantic 모델, DTO)
│ ├── user.py
│ └── item.py
│
├── /services # ❻ 핵심 비즈니스 로직 처리
│ ├── user_service.py
│ └── item_service.py
│
└── /api
└── /v1
├── __init__.py
└── /endpoints # ❼ API 경로(Endpoint) 정의 (라우터, Controller)
├── user.py
└── item.py
main.py: FastAPI 앱 인스턴스를 생성하고, api 디렉터리에 있는 라우터들을 포함시키는 역할만 하는 가벼운 진입점이다/core: 데이터베이스 주소, JWT 시크릿 키 등 프로젝트 전체에서 사용되는 설정 값을 관리한다/db: SQLAlchemy와 같은 데이터베이스 엔진과 세션 연결을 설정하는 코드를 보관한다/models: 데이터베이스의 테이블 구조를 파이썬 클래스로 정의한다. (예: SQLAlchemy의 ORM 모델)/schemas: API의 요청(Request)과 응답(Response) 데이터 형태를 Pydantic 모델로 정의한다. 데이터가 API에 들어오고 나갈 때의 유효성 검사를 담당한다./services: 실제 애플리케이션의 핵심 로직이 담기는 곳. "사용자를 생성한다", "상품 가격을 계산한다"와 같은 비즈니스 규칙을 함수로 구현한다./api/v1/endpoints: 사용자의 HTTP 요청을 직접 받는 부분이다. APIRouter를 사용해 엔드포인트를 정의하고, 요청이 오면 데이터를 검증한 뒤 적절한 서비스 함수를 호출하는 '교통정리' 역할을 한다./items/ 경로를 담당하는 함수가 요청을 받는다. 요청 본문(JSON)을 schemas.ItemCreate모델을 사용해 유효성을 검사한다.services.item_service.create_item() 함수의 인자로 넘겨 호출한다.db 세션을 사용해 models.Item객체를 생성한다. 핵심 비즈니스 로직이 여기서 실행된다.schemas.Item (응답용 스키마)에 맞춰 변환한 뒤, 최종 JSON 응답을 사용자에게 보낸다./my_project
├── main.py # FastAPI 앱 생성 및 라우터 등록 (Nest.js의 main.ts)
│
├── /routers # API 경로(Endpoint) 정의 계층 (Controller 역할)
│ ├── user_router.py
│ └── item_router.py
│
├── /services # 핵심 비즈니스 로직 처리 계층 (Service 역할)
│ ├── user_service.py
│ └── item_service.py
│
├── /schemas # 데이터 유효성 검증 및 형태 정의 (DTO - Data Transfer Object 역할)
│ ├── user_schema.py
│ └── item_schema.py
│
└── /models # 데이터베이스 ORM 모델 (Entity 역할)
└── user_model.py
└── item_model.py
Fast API는 높은 자유로움으로 개발자가 맘대로 구조를 짤 수 있다.
| 구분 항목 | Django (장고) | Flask (플라스크) | FastAPI |
|---|---|---|---|
| 철학 | "배터리 포함 (Batteries Included)" | "마이크로 프레임워크 (Microframework)" | "현대적, 고성능 API" |
| 핵심 특징 | 웹 개발에 필요한 모든 기능(ORM, 관리자 페이지, 인증 등)을 기본 제공. 풀스택(Full-stack) 개발에 적합. | 핵심 기능만 남긴 최소한의 구조. 필요한 기능은 라이브러리를 직접 추가하여 확장. | 비동기(ASGI) 기반의 압도적인 성능. API 개발에 특화된 기능(자동 문서화, 데이터 검증) 제공. |
| 성능 | 상대적으로 무겁고 느림. 동기(Synchronous) 방식이 기본. | 가볍지만, FastAPI보다는 느림. 동기(WSGI) 방식이 기본. | 가장 빠름. 비동기(Asynchronous) 처리를 통해 높은 동시성 처리 능력. |
| 개발 속도 | 정해진 규칙이 많아 복잡한 웹사이트를 빠르고 안정적으로 구축 가능. | 간단한 기능은 매우 빠르게 개발 가능. 규모가 커지면 설계 부담 증가. | 직관적인 코드와 자동 문서화 기능으로 API 개발 속도가 매우 빠름. |
| 주요 용도 | 복잡한 기능의 대형 웹사이트, CMS, 쇼핑몰 등 | 간단한 웹사이트, 프로토타입, 소규모 API, 자유로운 구조가 필요한 프로젝트 | 고성능 API 서버, 마이크로서비스 아키텍처(MSA), 실시간 웹 애플리케이션 |
| 난이도 | 배워야 할 내용이 많아 초기 진입 장벽이 높음. | 매우 쉬움. 파이썬 기본 지식만으로 시작 가능. | 쉬운 편. 단, 비동기 프로그래밍(async/await)에 대한 이해가 필요 |
pip install fastapi uvicorn[standard]
서버 역할을 해줄 Uvicorn을 설치해야한다.
main.py 파일을 만들고 코드를 작성한다. (아래는 예시 코드)
# main.py
from fastapi import FastAPI
# 1. FastAPI 앱 인스턴스 생성
app = FastAPI()
# 2. 경로(Endpoint)와 처리 함수 정의
# @app.get("/")는 아래 함수가 루트 경로("/")에 대한 GET 요청을 처리한다는 의미
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
FastAPI(): FastAPI 애플리케이션의 핵심 인스턴스를 생성@app.get("/"): 경로 작동 데코레이터. GET이라는 HTTP 메소드로 /라는 경로(URL)에 접속했을 때 바로 아래에 있는 함수를 실행uvicorn main:app --reload
main: main.py 파일을 의미app: main.py 파일 안에서 app = FastAPI()로 만든 객체를 의미-reload: 코드가 변경될 때마다 서버를 자동으로 재시작해주는 옵션 (개발용)Uvicorn running on http://127.0.0.1:8000 가 보이면 성공
1. "Hello World" 확인
http://127.0.0.1:8000을 입력하면 {"Hello": "World"} JSON 응답을 볼 수 있다2. 자동 API 문서 (Swagger UI)
http://127.0.0.1:8000/docs를 입력/items/{item_id}를 클릭하고 item_id에 숫자 5를 넣고 실행(Execute)할 수 있다1. 경로 매개변수 (Path Parameter)
URL 경로 자체에 들어가는 변수입니다. 위 예제의 {item_id}가 바로 경로 매개변수이다.
# /items/5 로 접속하면 item_id에 5가 들어옵니다.
@app.get("/items/{item_id}")
def read_item(item_id: int): # 타입 힌트(int)로 숫자만 받도록 설정
return {"item_id": item_id, "description": "This is an item."}
item_id: int처럼 타입 힌트를 주면 FastAPI가 자동으로 데이터 타입을 검증하고 변환하고, 만약 숫자가 아닌 값을 넣으면 에러를 반환한다.2. 쿼리 매개변수 (Query Parameter)
URL 뒤에 ?로 시작하는 key=value 형태의 값. 함수 매개변수에 경로에 없는 변수를 추가하면 FastAPI가 자동으로 쿼리 매개변수로 인식한다.
# /users?skip=0&limit=10 으로 접속
@app.get("/users")
def read_users(skip: int = 0, limit: int = 10):
return {"skip_value": skip, "limit_value": limit}
skip과 limit은 경로에 없으므로 쿼리 매개변수가 된다.= 0이나 = 10처럼 기본값을 설정하면, 해당 쿼리가 URL에 없을 때 이 값을 사용한다.3. 요청 본문 (Request Body)
회원가입이나 게시글 작성처럼 복잡한 데이터를 보낼 때는 POST 메소드와 함께 요청의 본문(Body)에 데이터를 실어 보낸다. FastAPI는 Pydantic 라이브러리를 사용해 이를 매우 효과적으로 처리한다.
pydantic의 BaseModel을 상속받아 데이터 모델을 먼저 정의.
# main.py 상단에 추가
from pydantic import BaseModel
# 아이템의 데이터 구조를 클래스로 정의
class Item(BaseModel):
name: str
price: float
is_offer: bool | None = None # 선택적 필드 (값이 없어도 됨)
# POST 요청을 처리할 경로 추가
@app.post("/items/")
def create_item(item: Item):
return {"item_name": item.name, "item_price": item.price}
create_item 함수의 매개변수로 item: Item을 선언하면, FastAPI는 요청 본문으로 들어온 JSON 데이터를 Item 클래스에 맞춰 자동으로 파싱하고 검증.name이 없거나 price가 숫자가 아니면 FastAPI가 알아서 상세한 에러 메시지를 반환한다./docs에 가보면 POST /items/ 엔드포인트가 추가되어 있고, 정해진 JSON 형식으로 데이터를 넣어 테스트해볼 수 있다.