📝 Add docs recommending `Union` over `Optional` and migrate source examples (#4908)
* 📝 Add docs recommending Union over Optional
* 📝 Update docs recommending Union over Optional
* 📝 Update source examples for docs, recommend Union over Optional
* 📝 Update highlighted lines with updated source examples
* 📝 Update highlighted lines in Markdown with recent code changes
* 📝 Update docs, use Union instead of Optional
* ♻️ Update source examples to recommend Union over Optional
* 🎨 Update highlighted code in Markdown after moving from Optional to Union
If you are using a Python version below 3.10, here's a tip from my very **subjective** point of view:
* 🚨 Avoid using `Optional[SomeType]`
* Instead ✨ **use `Union[SomeType, None]`** ✨.
Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.
I think `Union[str, SomeType]` is more explicit about what it means.
It's just about the words and names. But those words can affect how you and your teammates think about the code.
And then you won't have to worry about names like `Optional` and `Union`. 😎
#### Generic types
These types that take type parameters in square brackets are called **Generic types** or **Generics**, for example:
@ -422,6 +461,9 @@ An example from the official Pydantic docs:
You will see a lot more of all this in practice in the [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
!!! tip
Pydantic has a special behavior when you use `Optional` or `Union[Something, None]` without a default value, you can read more about it in the Pydantic docs about <ahref="https://pydantic-docs.helpmanual.io/usage/models/#required-optional-fields"class="external-link"target="_blank">Required Optional fields</a>.
## Type hints in **FastAPI**
**FastAPI** takes advantage of these type hints to do several things.
`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`.
@ -162,7 +161,7 @@ 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`:
@ -71,7 +71,7 @@ Pass `*`, as the first parameter of the function.
Python won't do anything with that `*`, but it will know that all the following parameters should be called as keyword arguments (key-value pairs), also known as <abbrtitle="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Even if they don't have a default value.
@ -75,7 +75,7 @@ En este caso el parámetro de la función `q` será opcional y será `None` por
!!! note "Nota"
FastAPI sabrá que `q` es opcional por el `= None`.
El `Optional` en `Optional[str]` no es usado por FastAPI (FastAPI solo usará la parte `str`), pero el `Optional[str]` le permitirá a tu editor ayudarte a encontrar errores en tu código.
El `Union` en `Union[str, None]` no es usado por FastAPI (FastAPI solo usará la parte `str`), pero el `Union[str, None]` le permitirá a tu editor ayudarte a encontrar errores en tu código.
파이썬은 `*`으로 아무런 행동도 하지 않지만, 따르는 매개변수들은 <abbrtitle="유래: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>로도 알려진 키워드 인자(키-값 쌍)여야 함을 인지합니다. 기본값을 가지고 있지 않더라도 그렇습니다.
O parâmetro de consulta `q` é do tipo `Optional[str]`, o que significa que é do tipo `str` mas que também pode ser `None`, e de fato, o valor padrão é `None`, então o FastAPI saberá que não é obrigatório.
O parâmetro de consulta `q` é do tipo `Union[str, None]`, o que significa que é do tipo `str` mas que também pode ser `None`, e de fato, o valor padrão é `None`, então o FastAPI saberá que não é obrigatório.
!!! note "Observação"
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
O `Optional` em `Optional[str]` não é usado pelo FastAPI, mas permitirá que seu editor lhe dê um melhor suporte e detecte erros.
O `Union` em `Union[str, None]` não é usado pelo FastAPI, mas permitirá que seu editor lhe dê um melhor suporte e detecte erros.
## Validação adicional
@ -35,18 +35,18 @@ Agora utilize-o como valor padrão do seu parâmetro, definindo o parâmetro `ma
Note que substituímos o valor padrão de `None` para `Query(None)`, o primeiro parâmetro de `Query` serve para o mesmo propósito: definir o valor padrão do parâmetro.
Note que substituímos o valor padrão de `None` para `Query(default=None)`, o primeiro parâmetro de `Query` serve para o mesmo propósito: definir o valor padrão do parâmetro.
Então:
```Python
q: Optional[str] = Query(None)
q: Union[str, None] = Query(default=None)
```
...Torna o parâmetro opcional, da mesma maneira que:
```Python
q: Optional[str] = None
q: Union[str, None] = None
```
Mas o declara explicitamente como um parâmetro de consulta.
@ -61,17 +61,17 @@ Mas o declara explicitamente como um parâmetro de consulta.
Ou com:
```Python
= Query(None)
= Query(default=None)
```
E irá utilizar o `None` para detectar que o parâmetro de consulta não é obrigatório.
O `Optional` é apenas para permitir que seu editor de texto lhe dê um melhor suporte.
O `Union` é apenas para permitir que seu editor de texto lhe dê um melhor suporte.
Então, podemos passar mais parâmetros para `Query`. Neste caso, o parâmetro `max_length` que se aplica a textos:
```Python
q: str = Query(None, max_length=50)
q: str = Query(default=None, max_length=50)
```
Isso irá validar os dados, mostrar um erro claro quando os dados forem inválidos, e documentar o parâmetro na *operação de rota* do esquema OpenAPI..
@ -80,7 +80,7 @@ Isso irá validar os dados, mostrar um erro claro quando os dados forem inválid
Você também pode incluir um parâmetro `min_length`:
@ -88,7 +88,7 @@ Você também pode incluir um parâmetro `min_length`:
Você pode definir uma <abbrtitle="Uma expressão regular, regex ou regexp é uma sequência de caracteres que define um parâmetro de busca para textos.">expressão regular</abbr> que combine com um padrão esperado pelo parâmetro: