#60.TIL | FastAPI 공식문서 따라하기(3)

Seongjae Hwang·2023년 1월 15일
0

https://slender-danger-059.notion.site/4-Query-Parameters-222b7c54d33c43f69c6df89921d90468

Query Parameters

path 파라미터가 아닌 값을 함수의 파라미터로 선언을 하게 되면, FastAPI는 자동적으로 이를 Query 파라미터로 인식을 하게 된다.

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]

여기서 query는 URL에서 ? 이후에 key-value 쌍으로 이루어지고 &로 분리가 된다.

예를 들어서 아래와 같은 URL이 있다고 하면,

http://127.0.0.1:8000/items/?skip=0&limit=10

query 파라미터는 다음과 같다.

  • skip : value는 0
  • limit : value는 10

또한, URL의 일부이므로 자연스럽게 타입은 string이 된다.

하지만, 파이썬 타입을 선언할 경우 해당 타입으로 변환이 된다. (위와 같은 경우는 query 파라미터 skip과 limit에 대한 value를 int로 타입을 지정하였다.)

Default

query 파라미터는 경로에서 고정된 부분이 아니고, 선택적일 수 있기 때문에 기본값을 가질 수 있다. 위 예시를 들었던 곳을 보면 skip=0, limit=10 이라는 기본값을 가지고 있다.

따라서,

http://127.0.0.1:8000/items/

로 이동을 하게 되면, 아래와 같은 URL로 이동한것과 똑같다.

http://127.0.0.1:8000/items/?skip=0&limit=10

또한, 아래와 같은 URL로 이동한 경우

http://127.0.0.1:8000/items/?skip=20

함수에서 매개변수의 값은 아래와 같게 된다.

  • skip=20 : URL에서 지정했기 때문에
  • limit=10 : default값으로 지정했기 때문에

Optional parameters

위에는 default값을 지정했다고 하면, 같은 방법으로 default값을 None으로 설정하여 선택적으로 파라미터를 받을 수 있다.

from typing import Union

from fastapi import FastAPI

app = 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}

따라서, 위와 같은 경우는 함수 query 파라미터 q는 선택적이고 default값으로 None을 가지게 된다. 만약 q의 값이 있다고 하면 str

Query parameter type conversion

bool 타입으로 선언할 수 있으며, 선언을 하면 다음과 같이 변환이 된다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
**async def read_item(item_id: str, q: str | None = None, short: bool = False):**
    item = {"item_id": item_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

이 경우 아래와 같이 1, True, true, on, yes 의 파라미터는 True로 처리를 하고, 반대의 값은 false로 처리를 한다. 그리고 str과 같은 타입과 맞지 않는 값을 파라미터로 전달하게 되면 타입 에러를 발생시킨다.

Multiple path and query parameters

한 API에서 다중으로 path파라미터와 query파라미터를 동시에 받을 경우 FastAPI는 순서와 상관없이 이름으로 구분을 한다.

from typing import Union

from fastapi import FastAPI

app = FastAPI()

**@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

Required query parameters

query 파라미터를 선택적으로 받기 위해서는 default값을 None으로 설정하여 해결할 수 있었다. 하지만, query 파라미터를 필수로 만들려면 기본값을 선언하여 해결할 수 있다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_user_item(item_id: str, needy: str):
    item = {"item_id": item_id, "needy": needy}
    return item

이렇게 되면 path 파라미터인 item_id 이후에 오는 needy 라는 query 파라미터는 필수로 와야되는 값이 된다. 따라서 브라우저에서 다음과 같은 URL을 연다면

http://127.0.0.1:8000/items/foo-item
{
    "detail": [
        {
            "loc": [
                "query",
                "needy"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

필수 query 파라미터인 needy를 넣지 않았기 때문에 위와 같은 오류를 보게 된다.

정리

일부 query 파라미터는 필수, 다른 일부는 default값, 또 다른 일부는 선택적으로 받을 수 있다.

from typing import Union

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_user_item(
    **item_id: str, needy: str, skip: int = 0, limit: Union[int, None] = None**
):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item

이와 같은 경우 3가지의 query 파라미터가 있다.

  • needy : 필수로 와야 되는 str
  • skip : default 값이 0 인 int
  • limit : 선택적인 값이며 값이 온다고 하면 int
profile
Always Awake

0개의 댓글