mirror of https://github.com/tiangolo/fastapi.git
📝 Add body multiple parameters docs
This commit is contained in:
parent
c432fc223c
commit
710df85566
|
|
@ -0,0 +1,167 @@
|
|||
Now that we have seen how to use `Path` and `Query`, let's see more advanced uses of request body declarations.
|
||||
|
||||
## Mix `Path`, `Query` and body parameters
|
||||
|
||||
First, of course, you can mix `Path`, `Query` and request body parameter declarations freely and **FastAPI** will know what to do.
|
||||
|
||||
```Python hl_lines="17 18 19"
|
||||
{!./tutorial/src/body-multiple-params/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Notice that, in this case, the `item` that would be taken from the body is optional. As it has a `None` default value.
|
||||
|
||||
|
||||
## Multiple body parameters
|
||||
|
||||
In the previous example, the endpoint would expect a JSON body with the attributes of an `Item`, like:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
}
|
||||
```
|
||||
|
||||
But you can also declare multiple body parameters, e.g. `item` and `user`:
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!./tutorial/src/body-multiple-params/tutorial002.py!}
|
||||
```
|
||||
|
||||
In this case, **FastAPI** will notice that there are more than one body parameter in the function (two parameters that are Pydantic models).
|
||||
|
||||
So, it will then use the parameter names as keys (field names) in the body, and expect a body like:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item": {
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
},
|
||||
"user": {
|
||||
"username": "dave",
|
||||
"full_name": "Dave Grohl"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Notice that even though the `item` was declared the same way as before, it is now expected to be inside of the body with a key `item`.
|
||||
|
||||
|
||||
**FastAPI** will do the automatic conversion from the request, so that the parameter `item` receives it's specific content and the same for `user`.
|
||||
|
||||
It will perform the validation of the compound data, and will document it like that for the OpenAPI schema and automatic docs.
|
||||
|
||||
## Singular values in body
|
||||
|
||||
The same way there is a `Query` and `Path` to define extra data for query and path parameters, **FastAPI** provides an equivalent `Body`.
|
||||
|
||||
For example, extending the previous model, you could decide that you want to have another key `importance` in the same body, besides the `item` and `user`.
|
||||
|
||||
If you declare it as is, because it is a singular value, **FastAPI** will assume that it is a query parameter.
|
||||
|
||||
But you can instruct **FastAPI** to treat it as another body key using `Body`:
|
||||
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!./tutorial/src/body-multiple-params/tutorial003.py!}
|
||||
```
|
||||
|
||||
In this case, **FastAPI** will expect a body like:
|
||||
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item": {
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
},
|
||||
"user": {
|
||||
"username": "dave",
|
||||
"full_name": "Dave Grohl"
|
||||
},
|
||||
"importance": 5
|
||||
}
|
||||
```
|
||||
|
||||
Again, it will convert the data types, validate, document, etc.
|
||||
|
||||
## Multiple body params and query
|
||||
|
||||
Of course, you can also declare additional query parameters whenever you need, additional to any body parameters.
|
||||
|
||||
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
|
||||
|
||||
```Python
|
||||
q: str = None
|
||||
```
|
||||
|
||||
as in:
|
||||
|
||||
```Python hl_lines="25"
|
||||
{!./tutorial/src/body-multiple-params/tutorial004.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
`Body` also has all the same extra validation and metadata parameters as `Query`,`Path` and others you will see later.
|
||||
|
||||
|
||||
## Embed a single body parameter
|
||||
|
||||
Let's say you only have a single `item` body parameter from a Pydantic model `Item`.
|
||||
|
||||
By default, **FastAPI** will then expect its body directly.
|
||||
|
||||
But if you want it to expect a JSON with a key `item` and inside of it the model contents, as it does when you declare extra body parameters, you can use the special `Body` parameter `embed`:
|
||||
|
||||
```Python
|
||||
item: Item = Body(..., embed=True)
|
||||
```
|
||||
|
||||
as in:
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!./tutorial/src/body-multiple-params/tutorial005.py!}
|
||||
```
|
||||
|
||||
In this case **FastAPI** will expect a body like:
|
||||
|
||||
```JSON hl_lines="2"
|
||||
{
|
||||
"item": {
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
instead of:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
}
|
||||
```
|
||||
|
||||
## Recap
|
||||
|
||||
You can add multiple body parameters to your function endpoint, even though a request can only have a single body.
|
||||
|
||||
But **FastAPI** will handle it, give you the correct data in your function, and validate and document the correct schema in the endpoint.
|
||||
|
||||
You can also declare singular values to be received as part of the body.
|
||||
|
||||
And you can instruct **FastAPI** to embed the body in a key even when there is only a single parameter declared.
|
||||
|
|
@ -101,3 +101,8 @@ And you can also declare numeric validations:
|
|||
* `ge`: `g`reater than or `e`qual
|
||||
* `lt`: `l`ess `t`han
|
||||
* `le`: `l`ess than or `e`qual
|
||||
|
||||
!!! info
|
||||
`Query`, `Path` and others you will see later are subclasses of a common `Param` class (that you don't need to use).
|
||||
|
||||
And all of them share the same all these same parameters of additional validation and metadata you have seen.
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
from fastapi import FastAPI, Path
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
description: str = None
|
||||
price: float
|
||||
tax: float = None
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
async def update_item(
|
||||
*,
|
||||
item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
|
||||
q: str,
|
||||
item: Item = None,
|
||||
):
|
||||
results = {"item_id": item_id}
|
||||
if q:
|
||||
results.update({"q": q})
|
||||
if item:
|
||||
results.update({"item": item})
|
||||
return results
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
description: str = None
|
||||
price: float
|
||||
tax: float = None
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
username: str
|
||||
full_name: str = None
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
async def update_item(*, item_id: int, item: Item, user: User):
|
||||
results = {"item_id": item_id, "item": item, "user": user}
|
||||
return results
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
from fastapi import Body, FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
description: str = None
|
||||
price: float
|
||||
tax: float = None
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
username: str
|
||||
full_name: str = None
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
async def update_item(
|
||||
*, item_id: int, item: Item, user: User, importance: int = Body(...)
|
||||
):
|
||||
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
|
||||
return results
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
from fastapi import Body, FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
description: str = None
|
||||
price: float
|
||||
tax: float = None
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
username: str
|
||||
full_name: str = None
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
async def update_item(
|
||||
*,
|
||||
item_id: int,
|
||||
item: Item,
|
||||
user: User,
|
||||
importance: int = Body(..., gt=0),
|
||||
q: str = None
|
||||
):
|
||||
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
|
||||
if q:
|
||||
results.update({"q": q})
|
||||
return results
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
from fastapi import Body, FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
description: str = None
|
||||
price: float
|
||||
tax: float = None
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
async def update_item(*, item_id: int, item: Item = Body(..., embed=True)):
|
||||
results = {"item_id": item_id, "item": item}
|
||||
return results
|
||||
|
|
@ -22,8 +22,9 @@ nav:
|
|||
- Path Parameters: 'tutorial/path-params.md'
|
||||
- Query Parameters: 'tutorial/query-params.md'
|
||||
- Request Body: 'tutorial/body.md'
|
||||
- Query Parameters - string validations: 'tutorial/query-params-str-validations.md'
|
||||
- Path Parameters - numeric validations: 'tutorial/path-params-numeric-validations.md'
|
||||
- Query Parameters - String Validations: 'tutorial/query-params-str-validations.md'
|
||||
- Path Parameters - Numeric Validations: 'tutorial/path-params-numeric-validations.md'
|
||||
- Body - Multiple Parameters: 'tutorial/body-multiple-params.md'
|
||||
- Concurrency and async / await: 'async.md'
|
||||
- Deployment: 'deployment.md'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue