늦었지만 처음으로 FastAPI를 사용해봤다. 생각보다 너무 강력하다.
- 빠르다. 공식문서에 따르면 Node나 Go와 비교할만 하다고 한다.
- 생산성이 높다. 써보면 알겠지만 '이것까지 자동화를 했어?' 하는 것까지 자동화 되어있다.
- 정적 타이핑이 용이하다.
아직 FastAPI의 모든 것을 속속들이 알지는 못하는지라, 1일차인 내가 느낀 장점은 이정도였다.
설치
$ pip install fastapi
$ pip install uvicorn
uvicorn은 ASGI(Asynchronous Server Gateway Interface)다. 비동기를 지원하는 WAS 라고 생각할 수 있다.
설치는 이렇게면 끝이다.
코드 살펴보기
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
async def root():
return {'message': 'Hello World'}
여기까지만 보면, Flask랑 큰 차이가 안 느껴질 수도 있다.
일단 눈에 띄는 것만 먼저 말하자면 async/await 지원한다.
실행
$ uvicorn main:app --reload()
실행을 해본다.
--reload
는 개발환경에서만 사용하며, Hot Reload다. 즉, 수정사항을 저장하면 반영된다.
http://localhost:8000
으로 가본다. 응답값으로 "Hello World"를 확인할 수 있다.
여기서 한번 더 이동해보자.
http://localhost:8000/docs
로 가본다. 설마? 그 설마다.
default로 swagger를 지원한다. 주석처리나 configuration이 전혀 필요 없었다.
나중에 더 놀라겠지만 param이나 querystring의 타입을 지정해주면 swagger가 자동으로 알아서 반영해준다.
pydantic에 힘입어 스키마도 쉽게 반영 가능하다.
놀라운 점들
경로 매개변
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
위 코드에서 item_id에는 int값이 자동으로 담긴다.
FastAPI가 param을 read_item
함수의 매개변수 값의 타입에 맞게 알아서 변환해준다.
만약 item_id
로 'some-title'과 같은 int형으로 변환 불가능한 문자열이 온다면 어떻게 될까?
validation도 자동이다.
{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
쿼리 매개변수
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip : skip + limit]
querystring도 마찬가지다. 위처럼 /items/
만 route로 제공되었는데, read_item
함수는 skip
, limit
이라는 매개변수를 받고 있다. FastAPI가 이걸 보면 skip
, limit
이 querystring으로 있을 것이라고 인지하고 자동으로 파싱하고 타입까지 변환해 준다.
Request Body
HTTP POST 요청과 같은 몇몇 요청들은 요청에 본문이 있다.
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
만약 item에 name
, description
, price
, tax
가 존재한다면?
위처럼 pydantic으로 모델을 만들고 함수의 매개변수에 타입 값으로 주면 된다.
FastAPI가 알아서 JSON으로 되어 있는 request body를 파싱하고 객체로 만들어 준다.
심지어 http://localhost:8000/docs에 들어가 보면 Item은 스키마로 변환되어 있다.
------------
오늘은 이 정도로 살펴봤지만, 이미 충분히 강력함을 느꼈다.
개인적으로 너무 마음에 들어서 앞으로 당분간은 FastAPI로 이것저것 만들어 볼 예정이다.