저번 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 는 그렇게 걸러진 쿼리 파라미터의 필터링을 수행하는 최종 함수이다.