Home > Software engineering >  FastAPI POST request with List input got 422 error
FastAPI POST request with List input got 422 error

Time:03-11

Hi I am newbie in FastAPI and want to write a POST request in which an input parameter is a list, but I got error 422 unprocessable entity:

{
  "detail": [
    {
      "loc": [
        "body"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

my POST request is:

@router.post('',status_code=200)
def register(reg_id: int, reg_name: str, reg_option_list:List[int]):
    reg_item = My_DB(
        id=reg_id,
        name=reg_name,
        option_list=reg_option_list,
    )
    item = db.query(My_DB).filter(My_DB.id == service_id).first()

    if item is not None:
        raise HTTPException(status_code=400, detail="Item exists.")
    db.add(reg_item)
    db.commit()
    return reg_item

But when I change my code like below, remove list input and set the value in code as a list, everything works fine:

@router.post('',status_code=200)
def register(reg_id: int, reg_name: str,):
    reg_item = My_DB(
        id=reg_id,
        name=reg_name,
        option_list=[1,2,3],
    )
    item = db.query(My_DB).filter(My_DB.id == service_id).first()

    if item is not None:
        raise HTTPException(status_code=400, detail="Item exists.")
    db.add(reg_item)
    db.commit()
    return reg_item

I will appreciate any help about my list input parameter. Thanks.

CodePudding user response:

As per the documentation (have a look at the "Tip" section)

To declare a query parameter with a type of list, like in the example above, you need to explicitly use Query, otherwise it would be interpreted as a request body.

Thus, by declaring a List parameter in the way you do, the endpoint expects to receive it as body, rather than query parameter. Hence, the 422 unprocessable entity error with the specific details you provided (i.e., body is missing). You could also check that through OpenAPI at, for instance, http://127.0.0.1:8000/docs. You would see that the value for reg_option_list is expected to be given in the Request body section.

The way to do this is to define the query parameter explicitly with Query, thus allowing the parameter appear multiple times in the URL. Example below:

from fastapi import Query
def register(reg_id: int, reg_name: str, reg_option_list: List[int] = Query(...)):

Also, remember to give path names to your routes, for instance /register, not empty strings ''.Sample URL to test:

/register?reg_id=1&reg_name=foo&reg_option_list=1&reg_option_list=2&reg_option_list=3
  • Related