# Modelo de resposta - Tipo de retorno

Você pode declarar o tipo usado para a resposta anotando o **tipo de retorno** *da função de operação de rota*.

Você pode usar **anotações de tipo** da mesma forma que usaria para dados de entrada em **parâmetros** de função, você pode usar modelos Pydantic, listas, dicionários, valores escalares como inteiros, booleanos, etc.

{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}

O FastAPI usará este tipo de retorno para:

* **Validar** os dados retornados.
    * Se os dados forem inválidos (por exemplo, se estiver faltando um campo), significa que o código do *seu* aplicativo está quebrado, não retornando o que deveria, e retornará um erro de servidor em vez de retornar dados incorretos. Dessa forma, você e seus clientes podem ter certeza de que receberão os dados e o formato de dados esperados.
* Adicionar um **Esquema JSON** para a resposta, na *operação de rota* do OpenAPI.
    * Isso será usado pela **documentação automática**.
    * Também será usado por ferramentas de geração automática de código do cliente.

Mas o mais importante:

* Ele **limitará e filtrará** os dados de saída para o que está definido no tipo de retorno.
    * Isso é particularmente importante para a **segurança**, veremos mais sobre isso abaixo.

## Parâmetro `response_model`

Existem alguns casos em que você precisa ou deseja retornar alguns dados que não são exatamente o que o tipo declara.

Por exemplo, você pode querer **retornar um dicionário** ou um objeto de banco de dados, mas **declará-lo como um modelo Pydantic**. Dessa forma, o modelo Pydantic faria toda a documentação de dados, validação, etc. para o objeto que você retornou (por exemplo, um dicionário ou objeto de banco de dados).

Se você adicionasse a anotação do tipo de retorno, ferramentas e editores reclamariam com um erro (correto) informando que sua função está retornando um tipo (por exemplo, um dict) diferente do que você declarou (por exemplo, um modelo Pydantic).

Nesses casos, você pode usar o parâmetro `response_model` do *decorador de operação de rota*  em vez do tipo de retorno.

Você pode usar o parâmetro `response_model` em qualquer uma das *operações de rota*:

* `@app.get()`
* `@app.post()`
* `@app.put()`
* `@app.delete()`
* etc.

{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}

/// note | Nota

Observe que `response_model` é um parâmetro do método "decorator" (`get`, `post`, etc). Não da sua *função de operação de rota*, como todos os parâmetros e corpo.

///

`response_model` recebe o mesmo tipo que você declararia para um campo de modelo Pydantic, então, pode ser um modelo Pydantic, mas também pode ser, por exemplo, uma `lista` de modelos Pydantic, como `List[Item]`.

O FastAPI usará este `response_model` para fazer toda a documentação de dados, validação, etc. e também para **converter e filtrar os dados de saída** para sua declaração de tipo.

/// tip | Dica

Se você tiver verificações de tipo rigorosas em seu editor, mypy, etc, você pode declarar o tipo de retorno da função como `Any`.

Dessa forma, você diz ao editor que está retornando qualquer coisa intencionalmente. Mas o FastAPI ainda fará a documentação de dados, validação, filtragem, etc. com o `response_model`.

///

### Prioridade `response_model`

Se você declarar tanto um tipo de retorno quanto um `response_model`, o `response_model` terá prioridade e será usado pelo FastAPI.

Dessa forma, você pode adicionar anotações de tipo corretas às suas funções, mesmo quando estiver retornando um tipo diferente do modelo de resposta, para ser usado pelo editor e ferramentas como mypy. E ainda assim você pode fazer com que o FastAPI faça a validação de dados, documentação, etc. usando o `response_model`.

Você também pode usar `response_model=None` para desabilitar a criação de um modelo de resposta para essa *operação de rota*, você pode precisar fazer isso se estiver adicionando anotações de tipo para coisas que não são campos Pydantic válidos, você verá um exemplo disso em uma das seções abaixo.

## Retorna os mesmos dados de entrada

Aqui estamos declarando um modelo `UserIn`, ele conterá uma senha em texto simples:

{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}

/// info | Informação

Para usar `EmailStr`, primeiro instale <a href="https://github.com/JoshData/python-email-validator" class="external-link" target="_blank">`email-validator`</a>.

Certifique-se de criar um [ambiente virtual](../virtual-environments.md){.internal-link target=_blank}, ative-o e instale-o, por exemplo:

```console
$ pip install email-validator
```

ou com:

```console
$ pip install "pydantic[email]"
```

///

E estamos usando este modelo para declarar nossa entrada e o mesmo modelo para declarar nossa saída:

{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}

Agora, sempre que um navegador estiver criando um usuário com uma senha, a API retornará a mesma senha na resposta.

Neste caso, pode não ser um problema, porque é o mesmo usuário enviando a senha.

Mas se usarmos o mesmo modelo para outra *operação de rota*, poderíamos estar enviando as senhas dos nossos usuários para todos os clientes.

/// danger | Perigo

Nunca armazene a senha simples de um usuário ou envie-a em uma resposta como esta, a menos que você saiba todas as ressalvas e saiba o que está fazendo.

///

## Adicionar um modelo de saída

Podemos, em vez disso, criar um modelo de entrada com a senha em texto simples e um modelo de saída sem ela:

{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}

Aqui, embora nossa *função de operação de rota* esteja retornando o mesmo usuário de entrada que contém a senha:

{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}

...declaramos o `response_model` como nosso modelo `UserOut`, que não inclui a senha:

{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}

Então, **FastAPI** cuidará de filtrar todos os dados que não são declarados no modelo de saída (usando Pydantic).

### `response_model` ou Tipo de Retorno

Neste caso, como os dois modelos são diferentes, se anotássemos o tipo de retorno da função como `UserOut`, o editor e as ferramentas reclamariam que estamos retornando um tipo inválido, pois são classes diferentes.

É por isso que neste exemplo temos que declará-lo no parâmetro `response_model`.

...mas continue lendo abaixo para ver como superar isso.

## Tipo de Retorno e Filtragem de Dados

Vamos continuar do exemplo anterior. Queríamos **anotar a função com um tipo**, mas queríamos poder retornar da função algo que realmente incluísse **mais dados**.

Queremos que o FastAPI continue **filtrando** os dados usando o modelo de resposta. Para que, embora a função retorne mais dados, a resposta inclua apenas os campos declarados no modelo de resposta.

No exemplo anterior, como as classes eram diferentes, tivemos que usar o parâmetro `response_model`. Mas isso também significa que não temos suporte do editor e das ferramentas verificando o tipo de retorno da função.

Mas na maioria dos casos em que precisamos fazer algo assim, queremos que o modelo apenas **filtre/remova** alguns dados como neste exemplo.

E nesses casos, podemos usar classes e herança para aproveitar as **anotações de tipo** de função para obter melhor suporte no editor e nas ferramentas, e ainda obter a **filtragem de dados** FastAPI.

{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}

Com isso, temos suporte de ferramentas, de editores e mypy, pois este código está correto em termos de tipos, mas também obtemos a filtragem de dados do FastAPI.

Como isso funciona? Vamos verificar. 🤓

### Anotações de tipo e ferramentas

Primeiro, vamos ver como editores, mypy e outras ferramentas veriam isso.

`BaseUser` tem os campos base. Então `UserIn` herda de `BaseUser` e adiciona o campo `password`, então, ele incluirá todos os campos de ambos os modelos.

Anotamos o tipo de retorno da função como `BaseUser`, mas na verdade estamos retornando uma instância `UserIn`.

O editor, mypy e outras ferramentas não reclamarão disso porque, em termos de digitação, `UserIn` é uma subclasse de `BaseUser`, o que significa que é um tipo *válido* quando o que é esperado é qualquer coisa que seja um `BaseUser`.

### Filtragem de dados FastAPI

Agora, para FastAPI, ele verá o tipo de retorno e garantirá que o que você retornar inclua **apenas** os campos que são declarados no tipo.

O FastAPI faz várias coisas internamente com o Pydantic para garantir que essas mesmas regras de herança de classe não sejam usadas para a filtragem de dados retornados, caso contrário, você pode acabar retornando muito mais dados do que o esperado.

Dessa forma, você pode obter o melhor dos dois mundos: anotações de tipo com **suporte a ferramentas** e **filtragem de dados**.

## Veja na documentação

Quando você vê a documentação automática, pode verificar se o modelo de entrada e o modelo de saída terão seus próprios esquemas JSON:

<img src="/img/tutorial/response-model/image01.png">

E ambos os modelos serão usados ​​para a documentação interativa da API:

<img src="/img/tutorial/response-model/image02.png">

## Outras anotações de tipo de retorno

Pode haver casos em que você retorna algo que não é um campo Pydantic válido e anota na função, apenas para obter o suporte fornecido pelas ferramentas (o editor, mypy, etc).

### Retornar uma resposta diretamente

O caso mais comum seria [retornar uma resposta diretamente, conforme explicado posteriormente na documentação avançada](../advanced/response-directly.md){.internal-link target=_blank}.

{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}

Este caso simples é tratado automaticamente pelo FastAPI porque a anotação do tipo de retorno é a classe (ou uma subclasse de) `Response`.

E as ferramentas também ficarão felizes porque `RedirectResponse` e ​​`JSONResponse` são subclasses de `Response`, então a anotação de tipo está correta.

### Anotar uma subclasse de resposta

Você também pode usar uma subclasse de `Response` na anotação de tipo:

{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}

Isso também funcionará porque `RedirectResponse` é uma subclasse de `Response`, e o FastAPI tratará automaticamente este caso simples.

### Anotações de Tipo de Retorno Inválido

Mas quando você retorna algum outro objeto arbitrário que não é um tipo Pydantic válido (por exemplo, um objeto de banco de dados) e você o anota dessa forma na função, o FastAPI tentará criar um modelo de resposta Pydantic a partir dessa anotação de tipo e falhará.

O mesmo aconteceria se você tivesse algo como uma <abbr title='Uma união entre vários tipos significa "qualquer um desses tipos".'>união</abbr> entre tipos diferentes onde um ou mais deles não são tipos Pydantic válidos, por exemplo, isso falharia 💥:

{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}

... isso falha porque a anotação de tipo não é um tipo Pydantic e não é apenas uma única classe ou subclasse `Response`, é uma união (qualquer uma das duas) entre um `Response` e ​​um `dict`.

### Desabilitar modelo de resposta

Continuando com o exemplo acima, você pode não querer ter a validação de dados padrão, documentação, filtragem, etc. que é realizada pelo FastAPI.

Mas você pode querer manter a anotação do tipo de retorno na função para obter o suporte de ferramentas como editores e verificadores de tipo (por exemplo, mypy).

Neste caso, você pode desabilitar a geração do modelo de resposta definindo `response_model=None`:

{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}

Isso fará com que o FastAPI pule a geração do modelo de resposta e, dessa forma, você pode ter quaisquer anotações de tipo de retorno que precisar sem afetar seu aplicativo FastAPI. 🤓

## Parâmetros de codificação do modelo de resposta

Seu modelo de resposta pode ter valores padrão, como:

{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}

* `description: Union[str, None] = None` (ou `str | None = None` no Python 3.10) tem um padrão de `None`.
* `tax: float = 10.5` tem um padrão de `10.5`.
* `tags: List[str] = []` tem um padrão de uma lista vazia: `[]`.

mas você pode querer omiti-los do resultado se eles não foram realmente armazenados.

Por exemplo, se você tem modelos com muitos atributos opcionais em um banco de dados NoSQL, mas não quer enviar respostas JSON muito longas cheias de valores padrão.

### Usar o parâmetro `response_model_exclude_unset`

Você pode definir o parâmetro `response_model_exclude_unset=True` do *decorador de operação de rota* :

{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}

e esses valores padrão não serão incluídos na resposta, apenas os valores realmente definidos.

Então, se você enviar uma solicitação para essa *operação de rota* para o item com ID `foo`, a resposta (sem incluir valores padrão) será:

```JSON
{
"name": "Foo",
"price": 50.2
}
```

/// info | Informação

No Pydantic v1, o método era chamado `.dict()`, ele foi descontinuado (mas ainda suportado) no Pydantic v2 e renomeado para `.model_dump()`.

Os exemplos aqui usam `.dict()` para compatibilidade com Pydantic v1, mas você deve usar `.model_dump()` em vez disso se puder usar Pydantic v2.

///

/// info | Informação

O FastAPI usa `.dict()` do modelo Pydantic com <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">seu parâmetro `exclude_unset`</a> para chegar a isso.

///

/// info | Informação

Você também pode usar:

* `response_model_exclude_defaults=True`
* `response_model_exclude_none=True`

conforme descrito na <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">documentação do Pydantic</a> para `exclude_defaults` e `exclude_none`.

///

#### Dados com valores para campos com padrões

Mas se seus dados tiverem valores para os campos do modelo com valores padrões, como o item com ID `bar`:

```Python hl_lines="3 5"
{
"name": "Bar",
"description": "The bartenders",
"price": 62,
"tax": 20.2
}
```

eles serão incluídos na resposta.

#### Dados com os mesmos valores que os padrões

Se os dados tiverem os mesmos valores que os padrões, como o item com ID `baz`:

```Python hl_lines="3 5-6"
{
"name": "Baz",
"description": None,
"price": 50.2,
"tax": 10.5,
"tags": []
}
```

O FastAPI é inteligente o suficiente (na verdade, o Pydantic é inteligente o suficiente) para perceber que, embora `description`, `tax` e `tags` tenham os mesmos valores que os padrões, eles foram definidos explicitamente (em vez de retirados dos padrões).

Portanto, eles serão incluídos na resposta JSON.

/// tip | Dica

Observe que os valores padrão podem ser qualquer coisa, não apenas `None`.

Eles podem ser uma lista (`[]`), um `float` de `10.5`, etc.

///

### `response_model_include` e `response_model_exclude`

Você também pode usar os parâmetros `response_model_include` e `response_model_exclude` do *decorador de operação de rota*.

Eles pegam um `set` de `str` com o nome dos atributos para incluir (omitindo o resto) ou para excluir (incluindo o resto).

Isso pode ser usado como um atalho rápido se você tiver apenas um modelo Pydantic e quiser remover alguns dados da saída.

/// tip | Dica

Mas ainda é recomendado usar as ideias acima, usando várias classes, em vez desses parâmetros.

Isso ocorre porque o Schema JSON gerado no OpenAPI do seu aplicativo (e a documentação) ainda será o único para o modelo completo, mesmo que você use `response_model_include` ou `response_model_exclude` para omitir alguns atributos.

Isso também se aplica ao `response_model_by_alias` que funciona de forma semelhante.

///

{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}

/// tip | Dica

A sintaxe `{"nome", "descrição"}` cria um `conjunto` com esses dois valores.

É equivalente a `set(["nome", "descrição"])`.

///

#### Usando `list`s em vez de `set`s

Se você esquecer de usar um `set` e usar uma `lista` ou `tupla` em vez disso, o FastAPI ainda o converterá em um `set` e funcionará corretamente:

{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}

## Recapitulação

Use o parâmetro `response_model` do *decorador de operação de rota* para definir modelos de resposta e, especialmente, para garantir que dados privados sejam filtrados.

Use `response_model_exclude_unset` para retornar apenas os valores definidos explicitamente.
