이전에는 주소 값에 "경로" 매개변수를 입력하여 전달 하였다면
이번에는 쿼리스트링이라 불리는 쿼리 매개변수를 전달하는 방법을 정리해본다.
#app.py
from fastapi import FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip : skip + limit]
fake_items_db 에 3개의 데이터가 있고 read_item()은 skip과 limit 변수를 받고, fake_items_db 데이터 중 반환 할 데이터를 슬라이싱 하여 반환한다.
skip은 생략 할 항목 갯수, limit은 반환 할 항목 갯수이다.
쿼리 매개변수는 ?로 명시하고 변수가 여러개일 경우&로 구분한다.
아래의 주소로 접속해보면
http://127.0.0.1:8000/items/?skip=0&limit=10

항목을 생략하지 않고 10개를 반환하게 하였으나 총 데이터가 3개만 존재하여 3개만 출력하고 있다.
skip: int = 0
limit: int = 10
skip과 limit은 int 타입만 입력이 가능하고 각각 0과 10이 기본값이다.
즉 http://localhost:8000/items/ 주소만 입력하면 쿼리 매개변수가 ?skip=0&limit=10 입력된 것과 동일하다.
생략할 경우 기본값이 적용되는 것을 보았고, 생략 하지 않고 필수입력이 되게 하려면 아래와 같이 수정하면 된다.
@app.get("/items/")
async def read_item(skip: int, limit: int = 10):
return fake_items_db[skip : skip + limit]
skip 타입만 명시할 경우 skip을 입력하지 않으면 오류가 발생한다.

변수를 선택적으로 입력되게 하려면 아래와 같이 적용 할 수 있다.
from typing import Union
from fastapi import FastAPI
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
q 변수를 생략하고 입력한 결과
여기서 주의할 점은 item_id는 경로 매개변수이다.
http://localhost:8000/items/아이템1

q 변수를 같이 입력한 결과
http://localhost:8000/items/아이템1?q=물약

파이썬 3.10버전 이상에서는 Union 대신 타입을 | 로 간단하게 표현 할 수도 있다.
async def read_item(item_id: str, q: str | None = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
bool 자료형을 쿼리 매개변수로 사용하기
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None, passive: bool = False):
item = {"item_id": item_id}
if q:
item.update({"q": q})
if not passive:
item.update(
{"설명": "패시브 효과 없음"}
)
return item
passive란 쿼리 매개변수를 boolean 타입으로 지정하였다. (적지 않을 경우 기본값 false)
신기하게 FastApi는 boolean 값이 1, true, on, yes 가 모두 참인 값으로 인식된다.
(false 인 값은 0, false, off, no)

아래처럼 경로 매개변수와 쿼리 매개변수를 다중으로 사용할 수도 있다.
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
user_id: int, item_id: str, q: Union[str, None] = None, short: bool = False
):
item = {"item_id": item_id, "owner_id": user_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item