committed by
GitHub
1 changed files with 240 additions and 0 deletions
@ -0,0 +1,240 @@ |
|||
# Retornos Adicionais no OpenAPI |
|||
|
|||
!!! warning "Aviso" |
|||
Este é um tema bem avançado. |
|||
|
|||
Se você está começando com o **FastAPI**, provavelmente você não precisa disso. |
|||
|
|||
Você pode declarar retornos adicionais, com códigos de status adicionais, media types, descrições, etc. |
|||
|
|||
Essas respostas adicionais serão incluídas no esquema do OpenAPI, e também aparecerão na documentação da API. |
|||
|
|||
Porém para as respostas adicionais, você deve garantir que está retornando um `Response` como por exemplo o `JSONResponse` diretamente, junto com o código de status e o conteúdo. |
|||
|
|||
## Retorno Adicional com `model` |
|||
|
|||
Você pode fornecer o parâmetro `responses` aos seus *decoradores de caminho*. |
|||
|
|||
Este parâmetro recebe um `dict`, as chaves são os códigos de status para cada retorno, como por exemplo `200`, e os valores são um outro `dict` com a informação de cada um deles. |
|||
|
|||
Cada um desses `dict` de retorno pode ter uma chave `model`, contendo um modelo do Pydantic, assim como o `response_model`. |
|||
|
|||
O **FastAPI** pegará este modelo, gerará o esquema JSON dele e incluirá no local correto do OpenAPI. |
|||
|
|||
Por exemplo, para declarar um outro retorno com o status code `404` e um modelo do Pydantic chamado `Message`, você pode escrever: |
|||
|
|||
```Python hl_lines="18 22" |
|||
{!../../../docs_src/additional_responses/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! note "Nota" |
|||
Lembre-se que você deve retornar o `JSONResponse` diretamente. |
|||
|
|||
!!! info "Informação" |
|||
A chave `model` não é parte do OpenAPI. |
|||
|
|||
O **FastAPI** pegará o modelo do Pydantic, gerará o `JSON Schema`, e adicionará no local correto. |
|||
|
|||
O local correto é: |
|||
|
|||
* Na chave `content`, que tem como valor um outro objeto JSON (`dict`) que contém: |
|||
* Uma chave com o media type, como por exemplo `application/json`, que contém como valor um outro objeto JSON, contendo:: |
|||
* Uma chave `schema`, que contém como valor o JSON Schema do modelo, sendo este o local correto. |
|||
* O **FastAPI** adiciona aqui a referência dos esquemas JSON globais que estão localizados em outro lugar, ao invés de incluí-lo diretamente. Deste modo, outras aplicações e clientes podem utilizar estes esquemas JSON diretamente, fornecer melhores ferramentas de geração de código, etc. |
|||
|
|||
O retorno gerado no OpenAI para esta *operação de caminho* será: |
|||
|
|||
```JSON hl_lines="3-12" |
|||
{ |
|||
"responses": { |
|||
"404": { |
|||
"description": "Additional Response", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/Message" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"200": { |
|||
"description": "Successful Response", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/Item" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"422": { |
|||
"description": "Validation Error", |
|||
"content": { |
|||
"application/json": { |
|||
"schema": { |
|||
"$ref": "#/components/schemas/HTTPValidationError" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Os esquemas são referenciados em outro local dentro do esquema OpenAPI: |
|||
|
|||
```JSON hl_lines="4-16" |
|||
{ |
|||
"components": { |
|||
"schemas": { |
|||
"Message": { |
|||
"title": "Message", |
|||
"required": [ |
|||
"message" |
|||
], |
|||
"type": "object", |
|||
"properties": { |
|||
"message": { |
|||
"title": "Message", |
|||
"type": "string" |
|||
} |
|||
} |
|||
}, |
|||
"Item": { |
|||
"title": "Item", |
|||
"required": [ |
|||
"id", |
|||
"value" |
|||
], |
|||
"type": "object", |
|||
"properties": { |
|||
"id": { |
|||
"title": "Id", |
|||
"type": "string" |
|||
}, |
|||
"value": { |
|||
"title": "Value", |
|||
"type": "string" |
|||
} |
|||
} |
|||
}, |
|||
"ValidationError": { |
|||
"title": "ValidationError", |
|||
"required": [ |
|||
"loc", |
|||
"msg", |
|||
"type" |
|||
], |
|||
"type": "object", |
|||
"properties": { |
|||
"loc": { |
|||
"title": "Location", |
|||
"type": "array", |
|||
"items": { |
|||
"type": "string" |
|||
} |
|||
}, |
|||
"msg": { |
|||
"title": "Message", |
|||
"type": "string" |
|||
}, |
|||
"type": { |
|||
"title": "Error Type", |
|||
"type": "string" |
|||
} |
|||
} |
|||
}, |
|||
"HTTPValidationError": { |
|||
"title": "HTTPValidationError", |
|||
"type": "object", |
|||
"properties": { |
|||
"detail": { |
|||
"title": "Detail", |
|||
"type": "array", |
|||
"items": { |
|||
"$ref": "#/components/schemas/ValidationError" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## Media types adicionais para o retorno principal |
|||
|
|||
Você pode utilizar o mesmo parâmetro `responses` para adicionar diferentes media types para o mesmo retorno principal. |
|||
|
|||
Por exemplo, você pode adicionar um media type adicional de `image/png`, declarando que a sua *operação de caminho* pode retornar um objeto JSON (com o media type `application/json`) ou uma imagem PNG: |
|||
|
|||
```Python hl_lines="19-24 28" |
|||
{!../../../docs_src/additional_responses/tutorial002.py!} |
|||
``` |
|||
|
|||
!!! note "Nota" |
|||
Note que você deve retornar a imagem utilizando um `FileResponse` diretamente. |
|||
|
|||
!!! info "Informação" |
|||
A menos que você especifique um media type diferente explicitamente em seu parâmetro `responses`, o FastAPI assumirá que o retorno possui o mesmo media type contido na classe principal de retorno (padrão `application/json`). |
|||
|
|||
Porém se você especificou uma classe de retorno com o valor `None` como media type, o FastAPI utilizará `application/json` para qualquer retorno adicional que possui um modelo associado. |
|||
|
|||
## Combinando informações |
|||
|
|||
Você também pode combinar informações de diferentes lugares, incluindo os parâmetros `response_model`, `status_code`, e `responses`. |
|||
|
|||
Você pode declarar um `response_model`, utilizando o código de status padrão `200` (ou um customizado caso você precise), e depois adicionar informações adicionais para esse mesmo retorno em `responses`, diretamente no esquema OpenAPI. |
|||
|
|||
O **FastAPI** manterá as informações adicionais do `responses`, e combinará com o esquema JSON do seu modelo. |
|||
|
|||
Por exemplo, você pode declarar um retorno com o código de status `404` que utiliza um modelo do Pydantic que possui um `description` customizado. |
|||
|
|||
E um retorno com o código de status `200` que utiliza o seu `response_model`, porém inclui um `example` customizado: |
|||
|
|||
```Python hl_lines="20-31" |
|||
{!../../../docs_src/additional_responses/tutorial003.py!} |
|||
``` |
|||
|
|||
Isso será combinado e incluído em seu OpenAPI, e disponibilizado na documentação da sua API: |
|||
|
|||
<img src="/img/tutorial/additional-responses/image01.png"> |
|||
|
|||
## Combinar retornos predefinidos e personalizados |
|||
|
|||
Você pode querer possuir alguns retornos predefinidos que são aplicados para diversas *operações de caminho*, porém você deseja combinar com retornos personalizados que são necessários para cada *operação de caminho*. |
|||
|
|||
Para estes casos, você pode utilizar a técnica do Python de "desempacotamento" de um `dict` utilizando `**dict_to_unpack`: |
|||
|
|||
```Python |
|||
old_dict = { |
|||
"old key": "old value", |
|||
"second old key": "second old value", |
|||
} |
|||
new_dict = {**old_dict, "new key": "new value"} |
|||
``` |
|||
|
|||
Aqui, o `new_dict` terá todos os pares de chave-valor do `old_dict` mais o novo par de chave-valor: |
|||
|
|||
```Python |
|||
{ |
|||
"old key": "old value", |
|||
"second old key": "second old value", |
|||
"new key": "new value", |
|||
} |
|||
``` |
|||
|
|||
Você pode utilizar essa técnica para reutilizar alguns retornos predefinidos nas suas *operações de caminho* e combiná-las com personalizações adicionais. |
|||
|
|||
Por exemplo: |
|||
|
|||
```Python hl_lines="13-17 26" |
|||
{!../../../docs_src/additional_responses/tutorial004.py!} |
|||
``` |
|||
|
|||
## Mais informações sobre retornos OpenAPI |
|||
|
|||
Para verificar exatamente o que você pode incluir nos retornos, você pode conferir estas seções na especificação do OpenAPI: |
|||
|
|||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responsesObject" class="external-link" target="_blank">Objeto de Retorno OpenAPI</a>, inclui o `Response Object`. |
|||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responseObject" class="external-link" target="_blank">Objeto de Retorno OpenAPI</a>, você pode incluir qualquer coisa dele diretamente em cada retorno dentro do seu parâmetro `responses`. Incluindo `description`, `headers`, `content` (dentro dele que você declara diferentes media types e esquemas JSON), e `links`. |
Loading…
Reference in new issue