FastAPI는 타입 힌트, 유효성 검사, 자동 OpenAPI 문서를 제공하여 빠르게 API를 만들 수 있게 해주는 현대적인 파이썬 프레임워크입니다. 기본 개념과 활용 방법을 배워보세요.

FastAPI는 명확한 코드와 자동 문서를 제공하면서 빠르게 웹 API를 구축하게 해주는 파이썬 프레임워크입니다. 작은 함수들(“엔드포인트”)을 작성해 API가 어떤 데이터를 받는지, 무엇을 반환하는지 선언하면 FastAPI가 라우팅, 유효성 검사, JSON 응답 생성 같은 웹 관련 작업을 처리합니다.
API는 한 소프트웨어가 다른 소프트웨어와 대화하게 해주는 URL 집합입니다.
예를 들어, 휴대폰의 날씨 앱은 GET /weather?city=Berlin 같은 URL을 호출할 수 있습니다. 서버는 온도와 예보 같은 구조화된 데이터(보통 JSON)로 응답합니다. 휴대폰 앱은 서버의 데이터베이스에 직접 접근할 필요 없이 API를 통해 결과를 받아 표시합니다.
FastAPI는 그 URL과 응답을 파이썬으로 쉽게 만들게 해줍니다.
비동기 전문가일 필요는 없습니다. 단순한 엔드포인트로 시작하고 필요에 따라 더 진보된 패턴을 도입하면 됩니다.
FastAPI는 파이썬으로 API를 만들 때 흔히 겪는 많은 마찰을 줄여주기 때문에 빠르게 확산되었습니다.
전통적인 API 프로젝트는 종종 느린 초기 설정과 많은 “배관작업”으로 시작합니다:
FastAPI의 핵심 기능은 이러한 문제를 직접적으로 겨냥해, 팀이 프레임워크 보일러플레이트와 싸우는 대신 엔드포인트 설계에 더 많은 시간을 쓰게 합니다.
FastAPI는 파이썬 타입 힌트를 적극적으로 사용합니다. 필드가 int, 선택적(optional), 또는 어떤 것의 리스트라고 선언하면 FastAPI는 이를 입력 검증과 출력 구조화에 활용합니다.
이로 인해 문자열 기반 실수(예: 어떤 곳에서는 ID를 텍스트로 취급하고 다른 곳에서는 숫자로 취급하는 실수)가 줄어들고 함수 시그니처에 명확한 기대값이 내장됩니다.
API 스키마가 코드에서 파생되므로 FastAPI는 대화형 문서를 자동으로 생성합니다(OpenAPI + Swagger UI/ReDoc). 이는 프론트엔드 개발자, QA, 통합 담당자가 엔드포인트를 탐색하고 요청을 시도하며 정확한 모델을 확인할 수 있게 해 팀 협업을 빠르게 만듭니다.
FastAPI가 잘못 설계된 API를 자동으로 고쳐주진 않습니다. 좋은 네이밍, 버전 관리, 오류 처리, 보안 결정은 여전히 필요합니다. 다만 아이디어에서 잘 정의된 API로 가는 경로를 더 깔끔하게 만들어 예기치 않은 문제를 줄여줍니다.
FastAPI는 몇 가지 핵심 아이디어를 이해하면 사용하기 훨씬 수월합니다. 내부 동작을 외우기보다 일상적으로 사용할 구성 요소들을 인지하는 것이 중요합니다.
프레임워크는 처음부터 만들 필요 없이 API를 구축하도록 도와주는 도구와 규약의 집합입니다. FastAPI는 엔드포인트 정의, 입력 읽기, 출력 반환, 오류 처리, 코드 조직화 등 일반적인 API 작업을 위한 배관을 제공합니다.
라우팅은 URL과 HTTP 메서드를 파이썬 코드에 연결하는 방법입니다.
예를 들어 GET /users를 “사용자 목록”에 매핑하고 POST /users를 “사용자 생성”에 매핑할 수 있습니다. FastAPI에서는 보통 @app.get(...), @app.post(...) 같은 데코레이터로 라우트를 정의해 API가 무엇을 제공하는지 한눈에 보이게 합니다.
모든 API 호출은 클라이언트가 보내는 요청과 서버가 반환하는 응답으로 구성됩니다.
FastAPI는 다음을 쉽게 해줍니다:
/users/{id}), 쿼리 문자열(?page=2), 헤더, 요청 본문에서 데이터 읽기200, 201, 404 등)로 구조화된 JSON 응답 반환FastAPI는 현대적인 파이썬 웹 서버 표준인 ASGI에서 실행됩니다. 실무적으로 이는 FastAPI가 많은 연결을 효율적으로 처리하도록 설계되었고, 필요할 때 WebSocket 같은 장기 연결 기능을 지원할 수 있다는 것을 의미합니다—낮은 수준의 네트워킹을 직접 관리할 필요가 없습니다.
파이썬 타입 힌트(예: str, int, list[Item])는 FastAPI에서 단순한 문서가 아니라 핵심 입력입니다. FastAPI는 이를 사용해 기대하는 데이터를 이해하고, 들어오는 값을 올바른 타입으로 변환하며, 더 예측 가능한 API를 만듭니다.
Pydantic 모델은 데이터의 형태(필드, 타입, 선택적 값)를 한 곳에 정의하게 해줍니다. FastAPI는 이 모델로 들어오는 JSON을 검증하고, 잘못된 입력을 거부하며(도움이 되는 에러 메시지 포함), 출력 직렬화를 일관되게 수행합니다. 그 결과 클라이언트가 엉망으로 데이터를 보낼 때도 API가 안정적으로 동작합니다.
FastAPI 앱은 엔드포인트(URL 경로 + HTTP 메서드)를 중심으로 구성됩니다. 엔드포인트는 클라이언트가 "무엇을 요청하는가"와 "어떻게 요청하는가"를 정의합니다. 예를 들어 클라이언트는 GET /users로 사용자 목록을 요청하거나 POST /users로 사용자를 생성할 수 있습니다.
경로는 라우트이고 메서드는 동작입니다:
GET /products → 데이터 조회POST /products → 생성PUT /products/123 → 교체/업데이트DELETE /products/123 → 삭제FastAPI는 URL의 일부로 포함되는 데이터와 요청의 선택적 필터를 분리합니다.
GET /users/42 → 42는 사용자 ID).? 뒤에 붙는 선택적 값입니다(예: GET /users?limit=10&active=true).클라이언트가 구조화된 데이터(보통 JSON)를 보낼 때는 요청 본문에 넣습니다. 일반적으로 POST나 PUT에서 사용됩니다.
예: POST /orders에 { "item_id": 3, "quantity": 2 } 같은 JSON을 보냅니다.
FastAPI는 평범한 파이썬 객체(예: dict)를 반환할 수 있지만, 응답 모델을 정의하면 더 빛을 발합니다. 응답 모델은 계약처럼 동작해 필드를 일관되게 형성하고, 불필요한 추가 데이터를 걸러내며, 타입을 강제합니다. 결과적으로 클라이언트는 무엇을 기대해야 할지 알게 되고 통합이 깨지는 일이 줄어듭니다.
“Async”(비동기)는 많은 요청을 효율적으로 처리하는 방식으로, 많은 시간이 대기(wait)에 소비될 때 유용합니다.
바리스타가 주문을 받을 때 에스프레소 머신이 작동하는 동안 가만히 서 있으면 손님을 적게 받을 수밖에 없습니다. 더 나은 방법은 커피를 시작한 뒤 그 사이에 다음 주문을 받는 것입니다.
Async는 이와 비슷합니다. FastAPI 앱은 네트워크 요청이나 데이터베이스 쿼리처럼 느리게 대기하는 작업을 시작한 뒤, 그 작업을 기다리는 동안 다른 들어오는 요청을 처리할 수 있습니다.
다음과 같은 I/O 중심 작업이 많은 경우에 비동기가 특히 도움이 됩니다:
비동기가 모든 것을 빠르게 만드는 마법 버튼은 아닙니다. 엔드포인트가 대부분 CPU 집약적(예: 대형 이미지 리사이징, 데이터 과학 계산, 큰 페이로드 암호화)이라면 비동기가 계산 속도를 높여주지 않습니다. 이런 경우에는 백그라운드 작업자, 프로세스 풀, 또는 스케일 아웃 같은 다른 전략이 필요합니다.
모든 코드를 비동기로 바꿀 필요 없습니다. 일반(동기) 경로 함수를 작성해도 FastAPI는 잘 실행합니다. 많은 프로젝트는 단순한 엔드포인트는 동기로 두고 데이터베이스 호출이나 외부 HTTP 요청처럼 명백히 도움이 되는 부분만 async def로 작성하는 식으로 혼합합니다.
유효성 검사는 외부로부터 들어오는 데이터를 코드로 넘기기 전의 검문소입니다. API가 입력(JSON 바디, 쿼리 파라미터, 경로 파라미터)을 받을 때 그 데이터가 완전하고 올바른 타입이며 합리적인 범위인지 확인해야 합니다.
FastAPI는 Pydantic 모델을 사용합니다. 한 번 "좋은 데이터"의 형태를 정의하면 FastAPI는 자동으로:
클라이언트가 잘못된 형태의 데이터를 보내면 FastAPI는 422 Unprocessable Entity와 함께 어떤 필드가 왜 잘못됐는지 지적하는 구조화된 오류 페이로드를 반환합니다. 이는 클라이언트 개발자가 요청을 빠르게 고치는 데 도움이 됩니다.
다음은 필수 필드, 타입, 최소/최대 제약, 형식 검사를 보여주는 작은 모델입니다:
from pydantic import BaseModel, EmailStr, Field
class UserCreate(BaseModel):
email: EmailStr
age: int = Field(ge=13, le=120)
username: str = Field(min_length=3, max_length=20)
email은 반드시 있어야 합니다.age는 정수여야 합니다.age는 13–120으로 제한됩니다.EmailStr은 유효한 이메일 형태를 강제합니다.같은 모델을 출력에 사용하면 API 응답이 내부 필드를 실수로 노출하지 않도록 하고, 올바른 필드 이름과 타입으로 JSON을 반환합니다.
FastAPI의 실용적인 기능 중 하나는 이미 작성한 코드 기반에서 자동으로 API 문서를 생성해준다는 점입니다.
OpenAPI는 API를 구조화된 형식(보통 JSON)으로 기술하는 표준 방식입니다. 이는 다음을 명시하는 "계약"입니다:
GET /users/{id})기계가 읽을 수 있으므로 도구들이 클라이언트 생성, 요청 검증, 팀 정렬 등에 활용할 수 있습니다.
FastAPI는 기본으로 두 가지 사람 친화적 문서 페이지를 제공합니다:
일반적으로 프로젝트에서 다음 경로에서 찾을 수 있습니다:
/docs (Swagger UI)/redoc (ReDoc)경로 파라미터, 요청/응답 모델, 유효성 검사 규칙을 변경하면 OpenAPI 스키마(그리고 문서 페이지)가 자동으로 업데이트됩니다. 별도의 "문서 유지보수" 단계가 필요하지 않습니다.
FastAPI 앱은 아주 작게 시작해도 "실제 같은" 느낌을 줍니다. 파이썬 객체 app을 만들고 라우트를 몇 개 추가한 뒤 로컬 서버를 실행해 브라우저에서 시도해보면 됩니다.
가장 작은 유용한 예제는 다음과 같습니다:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, FastAPI"}
이게 전부입니다: 하나의 라우트(GET /)가 JSON을 반환합니다.
API 느낌을 내기 위해 리스트에 항목을 저장해봅시다. 이는 데이터베이스가 아니므로 서버 재시작 시 데이터가 리셋되지만 학습용으로는 충분합니다.
from fastapi import FastAPI
app = FastAPI()
items = []
@app.post("/items")
def create_item(name: str):
item = {"id": len(items) + 1, "name": name}
items.append(item)
return item
@app.get("/items")
def list_items():
return items
이제 다음을 할 수 있습니다:
POST /items?name=Coffee로 항목 추가GET /items로 목록 조회일반적인 시작 구조는:
main.py(app 생성 및 라우트)requirements.txt 또는 pyproject.toml(의존성)일반적인 순서는:
uvicorn main:app --reload)http://127.0.0.1:8000 열어 엔드포인트를 시도FastAPI의 "의존성"은 엔드포인트가 필요로 하는 공통 입력(데이터베이스 세션, 현재 로그인한 사용자, 앱 설정, 공통 쿼리 파라미터 등)을 말합니다. 이들을 매 엔드포인트마다 직접 만들고 파싱하는 대신 한 번 정의하고 FastAPI가 필요한 곳에 주입하게 할 수 있습니다.
의존성은 보통 값을 반환하는 함수(또는 클래스)입니다. FastAPI는 해당 함수를 호출하고 필요한 매개변수를 분석해 결과를 엔드포인트에 주입합니다.
이를 의존성 주입이라 부르지만, 더 간단히 말하면 "필요한 것을 선언하면 FastAPI가 연결해준다"는 방식입니다.
의존성이 없으면 매 엔드포인트에서 다음을 반복할 수 있습니다:
의존성을 쓰면 이러한 로직을 중앙화할 수 있어 DB 세션 생성 방식이나 현재 사용자 로딩 방식을 바꿀 때 한 곳만 수정하면 됩니다.
page/limit 파싱 재사용많은 FastAPI 앱에서 보게 되는 패턴은 다음과 같습니다:
from fastapi import Depends, FastAPI
app = FastAPI()
def get_settings():
return {"items_per_page": 20}
@app.get("/items")
def list_items(settings=Depends(get_settings)):
return {"limit": settings["items_per_page"]}
Depends(...)로 의존성을 선언하면 FastAPI가 그 결과를 엔드포인트 매개변수로 전달합니다. get_db()나 get_current_user() 같은 복잡한 빌딩 블록에도 같은 방식이 적용되어 앱이 성장해도 코드를 깔끔하게 유지할 수 있습니다.
FastAPI가 자동으로 API를 보호해주진 않습니다—적절한 방식을 선택해 엔드포인트에 적용해야 합니다. 다행히 의존성 시스템 등을 통해 흔한 보안 패턴을 구현하기 쉬운 빌딩 블록을 제공합니다.
**인증(authentication)**은 "너는 누구냐?"를 답합니다. **권한(authorization)**은 "무엇을 할 수 있냐?"를 답합니다.
예: 사용자는 인증되어 있을 수 있지만 관리자 전용 라우트에 접근할 권한이 없을 수 있습니다.
X-API-Key)로 전송. 교체와 폐기를 관리해야 함.FastAPI는 fastapi.security 같은 유틸리티를 통해 이러한 방식을 지원하고 OpenAPI에 문서화할 수 있게 해줍니다.
사용자 비밀번호를 저장할 때는 평문 저장 금지. 솔트(salt)를 더한 느린 해시(bcrypt/argon2 등)를 사용하세요. 또한 무차별 대입 방어를 위한 레이트 리미팅과 계정 잠금 정책도 고려하세요.
보안은 세부 사항의 문제입니다: 토큰 저장 방식, CORS 설정, HTTPS, 비밀값 관리, 민감한 엔드포인트의 올바른 권한 검사 등. 내장 도구를 시작점으로 삼고, 프로덕션에 배포하기 전에는 코드 리뷰와 테스트로 접근 방식을 검증하세요.
테스트는 "내 환경에서 동작함"을 실제로 신뢰해 배포할 수 있게 만드는 단계입니다. 좋은 소식은 FastAPI가 Starlette 위에서 동작하므로 강력한 테스트 도구를 별도 설정 없이 사용할 수 있다는 점입니다.
단위 테스트는 작은 단위(값을 계산하는 함수, 현재 사용자를 로드하는 의존성, 데이터베이스와 통신하는 서비스 메서드(모킹))를 검증합니다.
통합 테스트는 엔드포인트를 끝에서 끝까지 호출해 전체 HTTP 응답을 검증합니다. 라우팅 실수, 의존성 연결 문제, 유효성 검사 문제를 잡아냅니다.
건강한 테스트 스위트는 보통 단위 테스트가 많고(빠름) 통합 테스트는 적은 편(높은 신뢰성)을 유지합니다.
FastAPI 앱은 Starlette의 TestClient를 사용해 프로세스 내에서 호출할 수 있습니다—서버를 띄우지 않아도 됩니다.
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_healthcheck():
r = client.get("/health")
assert r.status_code == 200
사용자와 다른 시스템이 의존하는 것들을 테스트하세요:
예측 가능한 데이터를 사용하고 외부 서비스를 격리(모킹 또는 테스트 DB 사용), 테스트 간 공유 상태를 피하세요. 빠른 테스트는 자주 실행되고, 느린 테스트는 건너뛰어집니다.
FastAPI 앱을 온라인에 올리는 것은 적절한 런너를 선택하고 몇 가지 프로덕션 필수 요소를 추가하는 일입니다.
로컬에서 uvicorn main:app --reload로 실행하면 개발 설정(자동 재시작, 자세한 에러 등)을 사용합니다.
프로덕션에서는 보통 --reload 없이 Uvicorn을 실행하거나 Gunicorn과 Uvicorn 워커 조합, 또는 리버스 프록시 뒤에서 실행합니다. 목표는 안정성: 통제된 재시작, 예측 가능한 성능, 안전한 기본 설정입니다.
일반 패턴:
이렇게 하면 파일을 편집하지 않고도 한 코드베이스로 여러 환경에 배포할 수 있습니다.
배포 전에 다음을 확인하세요:
/health 같은 엔드포인트로컬에서 동작하는 코드를 "배포 가능한 상태"로 옮길 때는 OpenAPI 출력을 CI에서 검증하거나 클라이언트를 자동 생성하는 워크플로우를 표준화하면 도움이 됩니다. Koder.ai 같은 도구는 초기 스캐폴딩(엔드포인트, 모델, 배포 준비 구조)을 채팅 기반으로 빠르게 생성해 검토/배포 파이프라인에 통합할 때 유용할 수 있습니다.
FastAPI는 파이썬으로 REST API를 깔끔하고 현대적으로 만들고 싶을 때 특히 좋은 선택입니다—요청/응답 모델이 명확하고 API가 성장하면서 예측 가능한 동작을 유지해야 할 때 유리합니다.
FastAPI는 다음과 같은 상황에서 강점을 보입니다:
항상 FastAPI가 최선은 아닙니다:
FastAPI 자체는 매우 빠를 수 있지만 실제 성능은 데이터베이스 호출, 네트워크 지연, 비즈니스 로직에 달려 있습니다. 프레임워크만으로 느린 I/O나 비효율적인 쿼리를 해결해주진 않습니다.
FastAPI가 적합해 보인다면 라우팅 패턴, Pydantic 모델, 데이터베이스 통합, 백그라운드 작업, 기본 인증에 집중하세요.
실용적인 경로는 작은 엔드포인트 세트를 만들어 확장하면서 재사용 가능한 의존성과 테스트를 추가하는 것입니다. 초기 스캐폴딩(routes, models, 배포 준비 구조)을 빠르게 진행하고 싶다면 사전 기획 모드(예: 채팅으로 엔드포인트 명세를 만들고 반복)에서 시작해 코드를 내보내 표준 리뷰/배포 파이프라인으로 진행하는 방법도 추천합니다.
FastAPI는 최소한의 보일러플레이트로 API를 구축하게 해주는 파이썬 웹 프레임워크입니다. 엔드포인트 함수(예: @app.get("/users"))를 작성하면 FastAPI가 라우팅, 요청 파싱, 유효성 검사, JSON 응답 생성을 처리합니다.
핵심 이점은 타입 힌트와 Pydantic 모델이 API가 무엇을 받는지와 반환하는지에 대한 명시적 계약 역할을 한다는 점입니다.
API는 다른 소프트웨어가 데이터 교환을 위해 호출하는 URL 집합(엔드포인트)입니다.
예를 들어 클라이언트는 GET /weather?city=Berlin 같은 요청으로 날씨 데이터를 요청하고, 서버는 구조화된 JSON으로 응답합니다. 클라이언트는 데이터베이스에 직접 접근할 필요 없이 API 응답만으로 동작합니다.
라우팅은 HTTP 메서드와 경로를 파이썬 함수에 연결하는 것입니다.
FastAPI에서는 보통 데코레이터를 사용합니다:
@app.get("/items") — 조회@app.post("/items") — 생성@app.put("/items/{id}") — 갱신/교체@app.delete("/items/{id}") — 삭제이 방식으로 코드만 보고도 API가 제공하는 기능을 한눈에 파악할 수 있습니다.
경로 파라미터는 URL 구조의 일부로 특정 리소스를 식별할 때 사용되며 보통 필수입니다.
GET /users/42 → 42는 경로 파라미터입니다.쿼리 파라미터는 ? 다음에 붙는 선택적 필터나 제어 값입니다.
Pydantic 모델은 데이터의 형태(필드, 타입, 선택적 값)를 정의합니다. FastAPI는 이를 사용해 다음을 자동으로 처리합니다:
유효성 검사에 실패하면 FastAPI는 보통 422 Unprocessable Entity와 어느 필드가 문제인지 알려주는 구조화된 오류를 반환합니다.
FastAPI는 엔드포인트, 타입 힌트, 모델로부터 자동으로 OpenAPI 스키마를 생성합니다.
보통 다음과 같은 대화형 문서를 기본으로 제공합니다:
/docs/redoc코드에서 파라미터나 모델을 변경하면 스키마와 문서도 자동으로 갱신되므로 문서 유지보수가 필요 없습니다.
엔드포인트가 입출력 대기(I/O)를 많이 하는 경우 async def를 사용하세요(예: 데이터베이스 호출, 외부 HTTP 요청, 파일/오브젝트 스토리지 작업).
다음 경우에는 일반 def를 사용해도 됩니다:
동기와 비동기 엔드포인트를 동일 앱에서 혼합해 사용하는 것도 일반적입니다.
의존성(Dependencies)은 Depends()를 통해 엔드포인트에 주입되는 재사용 가능한 구성 요소입니다.
보통 다음에 사용됩니다:
의존성을 사용하면 중복 코드를 줄이고 횡단 관심사(cross-cutting concern)를 한 곳에 모아 관리할 수 있습니다.
FastAPI는 기본적으로 API를 보호해주지 않으므로 직접 보안 방식을 선택하고 엔드포인트에 적용해야 합니다.
일반적인 패턴:
또한 다음을 지키세요:
테스트에는 Starlette의 TestClient(FastAPI에서 사용 가능)를 이용해 앱을 프로세스 내에서 호출하는 방식이 편리합니다(서버를 띄우지 않아도 됨).
검증해야 할 항목 예시:
배포 시에는 ASGI 서버(예: Uvicorn)를 사용하고 로깅, 헬스 체크(/health), 타임아웃, 환경별 설정 등 운영 필수 요소를 갖추세요.
GET /users?limit=10&active=true → limit, active는 쿼리 파라미터입니다.