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 매개변수
q
는Optional[str]
타입이다. - 즉,
str
타입이지만None
일 수도 있으며, 실제로 기본값은None
이므로 FastAPI는 required가 아님을 알 수 있다.
2. Additional validation
q
는 optional이지만 제공될 때마다 길이가 50자를 초과하지 않도록 강제할 수 있다.
1) Import Query
- 글자 수를 강제하려면, 먼저
fastapi
의Query
를 임포트한다.
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_length
가3
이고 기본값이"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로 만들 수 있다.
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은 다음과 같다.
- 여러 query 매개변수
q
의 값(foo
및bar
)을 path operation function 내부의 Pythonlist
에서 함수 매개변수q
로 수신한다.
- 이때의 해당 URL에 대한 response는 다음과 같다.
Note
- 위의 예제와 같이
list
타입으로 query 매개변수를 선언하려면,Query
를 명시적으로 사용해야 한다. - 그렇지 않은 경우 request body로 해석된다.
- 대화형 API 문서는 이에 따라 업데이트되어, 다음과 같이 여러 값을 허용하게 된다.
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는 다음과 같다.
- 물론 다음과 같이
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
를 사용해야 하는 경우를 가정해 보자.
- 위와 같이
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
- 어떠한 매개변수가 내부적으로 더 이상 사용되지 않는 경우가 발생할 수 있다.
- 그럼에도 불구하고 그 매개변수를 사용하는 클라이언트가 있을 수 있기 때문에 가시적으로는 그대로 두어야 한다.
- 이런 경우
Query
에deprecated=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
- 위의 예제를 실행하면 문서는 다음과 같이 표시하게 된다.