저번 Query Parameter 글에서 한 분이 댓글에 질문을 남겨주셨다.
필터링 처리를 쿼리파라미터로 7개 이상으로 받게될 경우 어떻게 해야하나요? 파이썬 패킹 처리를 할 것 같은데... FastAPI에서 어떻게 하는지 궁금하네요
이 부분은 나도 궁금해서 한번 실험을 해보았다.
from fastapi import Query
my_query_parmas = {"a": Query(...), "b": Query(None)}
@app.get("/")
async def p(*args, **kwargs):
pass
@app.get("/test")
async def p(x: dict = my_query_params):
print(x)
path url에 따로 path 파라미터가 없고, get 요청이니 따로 명시하지 않아도 Query param으로 인식이 될 것이다.
하지만 실패!
<http://0.0.0.0:8000/?x=2>
{
"detail":[
{
"loc":[
"query",
"args"
],
"msg":"field required",
"type":"value_error.missing"
},
{
"loc":[
"query",
"kwargs"
],
"msg":"field required",
"type":"value_error.missing"
}
]
}
<http://0.0.0.0:8000/test?x=2>
{'a': Query(Ellipsis), 'b': Query(None)}
args, kwargs 자체를 매개변수 이름으로 인식하고 해당 값이 없다고 에러를 일으킨다.
이렇게 보면, 쿼리 파라미터는 어쩔 수 없이 매개변수로 직접 이름을 명시해줘야하는 듯 하다.
하지만 쿼리 파라미터가 엄청 많아질 경우엔? 너무 불편하다.
그래서 나는 따로 filter 하는 함수, 클래스를 만들어 사용했다.
인턴하는 곳에서 Django → FastAPI 전환 작업을 했어서(현재는 pending이지만...) Django기반 url 쿼리 스트링, 예를 들어 id__in과 같은 형식에 맞춰서 코드를 짰다.
filter functions는 쿼리셋을 필터링하는 함수들이 모여있으며, 마지막 query_parser는 쿼리 스트링을 보고 해당 쿼리에 맞는 함수와 필드를 리턴해준다.
filter_class에는 FilterBase라는 추상 클래스가 존재하여, 기본적인 필터링 메소드를 제공한다.
fields
는 {"필드": ['메소드',..]
형식으로 허용할 필드와 메소드를 작성한다.
check_allowed_filter_func
는 쿼리 파라미터와 현재 허용되는 필드와 메소드가 아닌 것은 제거를 한다.
exec_filter
는 그렇게 걸러진 쿼리 파라미터의 필터링을 수행하는 최종 함수이다.