mirror of https://github.com/tiangolo/fastapi.git
📝 Add docs for response_model
This commit is contained in:
parent
0fdd807a53
commit
222b75ac0c
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
|
|
@ -130,6 +130,19 @@ uvicorn main:my_awesome_api --debug
|
|||
|
||||
The `@app.get("/")` tells **FastAPI** that the function right below is an endpoint and that it should go to the path route `/`.
|
||||
|
||||
You can also use other HTTP methods:
|
||||
|
||||
* `@app.post()`
|
||||
* `@app.put()`
|
||||
* `@app.delete()`
|
||||
|
||||
And more exotic ones:
|
||||
|
||||
* `@app.options()`
|
||||
* `@app.head()`
|
||||
* `@app.patch()`
|
||||
* `@app.trace()`
|
||||
|
||||
### Step 4: define the endpoint function
|
||||
|
||||
```Python hl_lines="7"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
You can declare the model used for the response with the parameter `response_model` in any of the endpoint creation methods:
|
||||
|
||||
* `@app.get()`
|
||||
* `@app.post()`
|
||||
* `@app.put()`
|
||||
* `@app.delete()`
|
||||
* etc.
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!./tutorial/src/response-model/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc), not of your endpoint function like all the parameters and body.
|
||||
|
||||
It receives a standard Pydantic model and will:
|
||||
|
||||
* Convert the output data to the type declarations of the model
|
||||
* Validate the data
|
||||
* Add a JSON Schema for the response, in the OpenAPI endpoint
|
||||
* Will be used by the automatic documentation systems
|
||||
|
||||
But most importantly:
|
||||
|
||||
* Will limit the output data to that of the model. We'll see how that's important below.
|
||||
|
||||
## Return the same input data
|
||||
|
||||
Here we are declaring a `UserIn` model, it will contain a plaintext password:
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!./tutorial/src/response-model/tutorial002.py!}
|
||||
```
|
||||
|
||||
And we are using this model to declare our input and the same model to declare our output:
|
||||
|
||||
```Python hl_lines="16 17"
|
||||
{!./tutorial/src/response-model/tutorial002.py!}
|
||||
```
|
||||
|
||||
Now, whenever a browser is creating a user with a password, the API will return the same password in the response.
|
||||
|
||||
In this case, it might not be a problem, becase the user himself is sending the password.
|
||||
|
||||
But if we use sthe same model for another endpoint, we could be sending the passwords of our users to every client.
|
||||
|
||||
!!! danger
|
||||
Never send the plain password of a user in a response.
|
||||
|
||||
## Add an output model
|
||||
|
||||
We can instead create an input model with the plaintext password and an output model without it:
|
||||
|
||||
```Python hl_lines="8 10 15"
|
||||
{!./tutorial/src/response-model/tutorial003.py!}
|
||||
```
|
||||
|
||||
Here, even though our endpoint function is returning the same input user that contains the password:
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!./tutorial/src/response-model/tutorial003.py!}
|
||||
```
|
||||
|
||||
...we declared the `response_model` to be our model `UserOut`, that doesn't include the password:
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!./tutorial/src/response-model/tutorial003.py!}
|
||||
```
|
||||
|
||||
So, **FastAPI** will take care of filtering out all the data that is not declared in the output model (using Pydantic).
|
||||
|
||||
## See it in the docs
|
||||
|
||||
When you see the automatic docs, you can check that the input model and output model will both have their own JSON Schema:
|
||||
|
||||
<img src="/img/tutorial/response-model/image01.png">
|
||||
|
||||
And both models will be used for the interactive API documentation:
|
||||
|
||||
<img src="/img/tutorial/response-model/image02.png">
|
||||
|
||||
## Recap
|
||||
|
||||
Use the endpoint decorator's parameter `response_model` to define response models and especially to ensure private data is filtered out.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Set
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
description: str = None
|
||||
price: float
|
||||
tax: float = None
|
||||
tags: Set[str] = []
|
||||
|
||||
|
||||
@app.post("/items/", response_model=Item)
|
||||
async def create_item(*, item: Item):
|
||||
return item
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
from pydantic.types import EmailStr
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class UserIn(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
email: EmailStr
|
||||
full_name: str = None
|
||||
|
||||
|
||||
# Don't do this in production!
|
||||
@app.post("/user/", response_model=UserIn)
|
||||
async def create_user(*, user: UserIn):
|
||||
return user
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
from pydantic.types import EmailStr
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class UserIn(BaseModel):
|
||||
username: str
|
||||
password: str
|
||||
email: EmailStr
|
||||
full_name: str = None
|
||||
|
||||
|
||||
class UserOut(BaseModel):
|
||||
username: str
|
||||
email: EmailStr
|
||||
full_name: str = None
|
||||
|
||||
|
||||
@app.post("/user/", response_model=UserOut)
|
||||
async def create_user(*, user: UserIn):
|
||||
return user
|
||||
|
|
@ -29,6 +29,7 @@ nav:
|
|||
- Body - Nested Models: 'tutorial/body-nested-models.md'
|
||||
- Cookie Parameters: 'tutorial/cookie-params.md'
|
||||
- Header Parameters: 'tutorial/header-params.md'
|
||||
- Response Model: 'tutorial/response-model.md'
|
||||
- Concurrency and async / await: 'async.md'
|
||||
- Deployment: 'deployment.md'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue