Skip to content

6. Query Parameters and String Validations


1. Query Parameters and String Validations

  • FastAPI를 사용하면 매개변수에 대한 추가 정보 및 유효성 검사를 선언할 수 있다.


from typing import Optional
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/")
async def read_items(q: Optional[str] = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


  • 위의 예제와 같이 query 매개변수 qOptional[str] 타입이다.
  • 즉, str 타입이지만 None일 수도 있으며, 실제로 기본값은 None이므로 FastAPI는 required가 아님을 알 수 있다.


2. Additional validation

  • q는 optional이지만 제공될 때마다 길이가 50자를 초과하지 않도록 강제할 수 있다.


1) Import Query

  • 글자 수를 강제하려면, 먼저 fastapiQuery를 임포트한다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, max_length=50)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


2) Use Query as the default value

  • 이제 query 매개변수의 기본값으로 사용하고, max_length를 50으로 설정한다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, max_length=50)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


  • 기본값으로 None을 사용했었지만, 추가적인 유효성 검사를 위해 Query(None)으로 바꿔야 한다.
  • 즉, Query의 첫 번째 매개변수는 해당 기본값을 정의하는 것과 동일한 목적을 수행한다.
  • Query를 사용하면 None뿐만 아니라 max_length=50과 같이 더 많은 매개변수를 전달할 수 있다.
  • 이렇게 하면 데이터의 유효성을 검사하고, 데이터가 유효하지 않은 경우 에러를 표시한다.


3) Add more validations

  • min_length 매개변수 또한 추가할 수 있다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, min_length=3, max_length=50)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


4) Add regular expressions

  • 매개변수가 일치해야 하는 경우 정규 표현식으로 정의할 수 있다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^fixedquery$")
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


3. Default values

  • 기본값으로 사용할 첫 번째 인수로 None을 전달할 수 있는 것과 같은 방법으로 None 대신 다른 값을 전달할 수 있다.


  • 다음의 예제는 min_length3이고 기본값이 "fixedquery"인 query 매개변수 q를 선언하는 예제이다.


from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: str = Query("fixedquery", min_length=3)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


4. Make it required

  • 더 많은 유효성 검사 또는 메타데이터를 선언할 필요가 없는 경우 다음과 같이 기본값을 선언하지 않음으로써, query 매개변수 q를 required로 만들 수 있다.


q: str


  • Query를 사용하여 required로 만드는 방법은 다음과 같다.


from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: str = Query(..., min_length=3)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


  • 위의 예제와 같이 Query의 첫 번째 인수로 ...을 전달하면 required로 선언된다.


Note

  • ...은 Python의 특별한 단일 값이며, "Ellipsis"라고 한다.


5. Query parameter list / multiple values

  • Query로 query 매개변수를 명시적으로 정의하면, 리스트나 여러 값을 받도록 선언할 수 있다.


  • 다음의 예제는 URL에 여러 번 나타날 수 있는 query 매개변수 q를 선언하는 예제이다.


from typing import List, Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: Optional[List[str]] = Query(None)):
    query_items = {"q": q}

    return query_items


  • 위의 예제를 실행한 후 URL은 다음과 같다.


http://localhost:8000/items/?q=foo&q=bar


  • 여러 query 매개변수 q의 값(foobar)을 path operation function 내부의 Python list에서 함수 매개변수 q로 수신한다.


  • 이때의 해당 URL에 대한 response는 다음과 같다.


{
  "q": ["foo", "bar"]
}


Note

  • 위의 예제와 같이 list 타입으로 query 매개변수를 선언하려면, Query를 명시적으로 사용해야 한다.
  • 그렇지 않은 경우 request body로 해석된다.


  • 대화형 API 문서는 이에 따라 업데이트되어, 다음과 같이 여러 값을 허용하게 된다.


001


1) Query parameter list / multiple values with defaults

  • 값이 아무것도 제공되지 않을 경우 default list를 정의할 수 있다.


from typing import List
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: List[str] = Query(["foo", "bar"])):
    query_items = {"q": q}

    return query_items


  • q의 기본값은 ["foo", "bar"]가 될 것이므로 이때의 response는 다음과 같다.


{
  "q": ["foo", "bar"]
}


  • 물론 다음과 같이 List[str] 대신 list를 사용해도 된다.


from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: list = Query([])):
    query_items = {"q": q}

    return query_items


Note

  • 하지만 위의 예제와 같이 list를 사용하는 경우, FastAPI는 리스트의 내용을 확인하지 않는다.
  • 예를 들어 List[int]는 리스트의 내용이 정수인지 확인하고 문서화하는 반면, list을 사용하는 경우 확인하지 않게 된다.
  • 그러므로 가능한 List[int]의 형태를 사용한다.


6. Declare more metadata

  • 매개변수에 대한 자세한 정보를 추가할 수 있다.
  • 해당 정보는 생성된 OpenAPI에 포함되고 문서 사용자 인터페이스 및 외부 도구에서 사용된다.


  • 다음과 같이 title을 추가할 수 있다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    q: Optional[str] = Query(None, title="Query string", min_length=3)
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


  • 그리고 description 또한 추가할 수 있다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    q: Optional[str] = Query(
        None,
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
    )
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


7. Alias parameters

  • 다음과 같이 query 매개변수명으로 item-query를 사용해야 하는 경우를 가정해 보자.


http://127.0.0.1:8000/items/?item-query=foobaritems


  • 위와 같이 item-query라는 매개변수명을 사용하고 싶지만, -이 포함된 경우 Python 변수명으로 사용할 수 없게 된다.
  • 이런 경우 다음과 같이 alias를 선언하여 문제를 해결할 수 있다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, alias="item-query")):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


  • 이제 query 매개변수명 q 대신 item-query로 인식된다.


8. Deprecating parameters

  • 어떠한 매개변수가 내부적으로 더 이상 사용되지 않는 경우가 발생할 수 있다.
  • 그럼에도 불구하고 그 매개변수를 사용하는 클라이언트가 있을 수 있기 때문에 가시적으로는 그대로 두어야 한다.
  • 이런 경우 Querydeprecated=True를 전달하여 이 매개변수는 명시적으로 사용되지 않는 것이라고 표시한다.


from typing import Optional
from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/items/")
async def read_items(
    q: Optional[str] = Query(
        None,
        alias="item-query",
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
        max_length=50,
        regex="^fixedquery$",
        deprecated=True,
    )
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}

    if q:
        results.update({"q": q})

    return results


  • 위의 예제를 실행하면 문서는 다음과 같이 표시하게 된다.


002


References