Fast API 알아보기

박지성 ·2025년 9월 5일
post-thumbnail

Python 3.7+를 기반으로 API를 구축하기 위한 빠른 웹 프레임워크
이름 그대로 Fast(빠름)을 핵심 가치로 세운다.

Fast API는 핵심적인 파이썬 라이브러리, Starlette와 Pydantic에 기반한다.

각각 알아보자.

Starlette(ASGI)

  • 웹 서버와의 통신을 위해 기존의 WSGI 대신 ASGI를 사용하는 경량 웹 프레임워크인 Starlette을 기반으로 동작한다
  • (ASGI)는 비동기 처리를 지원하기 때문에 Fast api도 비동기 처리가 지원된다.

ASGI : 비동기 처리
WSGI : 동기 처리

Pydantic

  • 파이썬의 타입 힌트(Type Hints)를 활용하여 데이터의 유효성을 검사하고 설정을 관리하는 라이브러리

  • 그냥 이 라이브러리가 타입 힌트 & 유효성 검사를 진행한다고 보면 되는 것 같다

Uvicorn

Fast API는 Uvicorn(ASGI) 위에서 동작한다 Uvicorn는 뭘까?

Uvicorn은 파이썬을 위해 만들어진 웹 서버 (비동기 처리가 특징이다)
자바는 톰캣, 파이썬은 Uvicorn 요런 느낌


일반적인 특징

  • 아주 빠름 : 파이썬 웹 프레임워크 중 가장 빠른편
  • 자동 API 문서화 : 코드를 작성하면 Swagger UI와 Redoc 두 종류의 API 문서를 자동으로 생성
    • /docs  Swagger UI를 통해 API를 직접 호출하고 테스트해볼 수 있음.
    • /redoc 경정리된 API 명세를 확인할 수 있음.
  • 타입 힌트와 자동 완성 : Pydantic를 사용하기 때문에 자동완성과 타입 체크를 해준다
  • 표준 기반 : OpenApi, JSON Schema등 공개 표준을 기반으로 구축되어 있음

프로젝트 구조

기본적인 프로젝트 구조

/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를 사용해 엔드포인트를 정의하고, 요청이 오면 데이터를 검증한 뒤 적절한 서비스 함수를 호출하는 '교통정리' 역할을 한다.

데이터 흐름

  • Endpoints (라우터)/items/ 경로를 담당하는 함수가 요청을 받는다. 요청 본문(JSON)을 schemas.ItemCreate모델을 사용해 유효성을 검사한다.
  • 라우터 → Services (서비스): 유효성 검사를 통과한 데이터를 services.item_service.create_item() 함수의 인자로 넘겨 호출한다.
  • Services (서비스): 전달받은 데이터를 가공하고, 데이터베이스에 저장하기 위해 db 세션을 사용해 models.Item객체를 생성한다. 핵심 비즈니스 로직이 여기서 실행된다.
  • 서비스 → 라우터: 데이터베이스에 저장된 후 생성된 아이템 객체를 다시 라우터로 반환한다.
  • 라우터 → 사용자: 서비스로부터 받은 객체를 schemas.Item (응답용 스키마)에 맞춰 변환한 뒤, 최종 JSON 응답을 사용자에게 보낸다.

Nest,spring 같은 구조도 가능

/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)에 대한 이해가 필요

사용법을 알아보자

1. 설치하기

pip install fastapi uvicorn[standard]

서버 역할을 해줄 Uvicorn을 설치해야한다.

2. 코드 작성하기

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)에 접속했을 때 바로 아래에 있는 함수를 실행

3. 서버 실행하기

uvicorn main:app --reload
  • mainmain.py 파일을 의미
  • appmain.py 파일 안에서 app = FastAPI()로 만든 객체를 의미
  • -reload: 코드가 변경될 때마다 서버를 자동으로 재시작해주는 옵션 (개발용)

Uvicorn running on http://127.0.0.1:8000 가 보이면 성공

4. 확인 및 테스트

1. "Hello World" 확인

  • 주소창에 http://127.0.0.1:8000을 입력하면 {"Hello": "World"} JSON 응답을 볼 수 있다

2. 자동 API 문서 (Swagger UI)

  • 주소창에 http://127.0.0.1:8000/docs를 입력
  • 만든 API들의 목록이 자동으로 문서화되어 나타난다. 여기서 각 API를 직접 테스트하고 실행해 볼 수 있다. /items/{item_id}를 클릭하고 item_id에 숫자 5를 넣고 실행(Execute)할 수 있다

5. 다양한 입력 다루기(처리하기)

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 형식으로 데이터를 넣어 테스트해볼 수 있다.
profile
개발 블로그 맞음.

0개의 댓글