diff --git a/aulas/07.md b/aulas/07.md index 9563098b..7fb3f9d9 100644 --- a/aulas/07.md +++ b/aulas/07.md @@ -541,6 +541,75 @@ def login_for_access_token(form_data: OAuth2Form, session: Session): Através do uso de tipos `Annotated`, conseguimos reutilizar os mesmos consistentemente, reduzindo a repetição de código e aumentando a eficiência do nosso trabalho. + +## Parâmetros de query via Pydantic + +Agora que conhecemos o tipo `Annotated`, podemos introduzir um novo conceito para as querystrings. No endpoint de listagem, estamos passando parâmetros específicos na URL para paginar a quantidade de objetos. + +Com `skip` e `offset`. Reduzindo a quantidade de objetos na resposta: + +```py title="fast_zero/routers/users.py" hl_lines="3 5" +@app.get('/', response_model=UserList) +def read_users( + skip: int = 0, limit: int = 100, session: Session = Depends(get_session) +): + users = session.scalars(select(User).offset(skip).limit(limit)).all() + return {'users': users} +``` + +Embora isso não seja efetivamente um problema, parâmetros de `offset` e `limit` são bastante genéricos e podem ser usados em qualquer endpoint que precisar de paginação. Uma boa pratica de organização é seria um modelo do pydantic especializado em filtros, como: + + +```py title="fast_zero/schemas.py" +class FilterPage(BaseModel): + offset: int = 0 + limit: int = 100 +``` + +Dessa forma, qualquer endpoint que precisar paginar resultados podem se beneficiar desse modelo. + + +### Implementação de querystrings via Pydantic + +Com esse modelo, podemos importar o objeto `Query` do Fastapi no arquivo de rotas e passar o modelo de filtro via o tipo `Annotated` em conjunto: + +```py title="fast_zero/routers/users.py" hl_lines="1 6 16" +from fastapi import APIRouter, Depends, HTTPException, Query + +# ... + +from fast_zero.schemas import ( + FilterPage, + Message, + UserList, + UserPublic, + UserSchema, +) + +# ... + +@router.get('/', response_model=UserList) +def read_users(session: Session, filter_users: Annotated[FilterPage, Query()]): + ... +``` + +Por conta da anotação com o tipo `Query()` a documentação mantém os parâmetros com o formato de querystrings na documentação: + +![Captura de tela da queristring no enpoint de listagem](assets/07/query_strings_pydantic.png){: .center } + + +E o uso do modelo `FilterPage` funciona da mesma forma que qualquer modelo do pydantic, acessando os atributos via ponto: + +```py title="fast_zero/routers/users.py" hl_lines="2 4" +@router.get('/', response_model=UserList) +def read_users(session: Session, filter_users: Annotated[FilterPage, Query()]): + users = session.scalars( + select(User).offset(filter_users.offset).limit(filter_users.limit) + ).all() +``` + +Isso além de simplificar o reuso das queries em outros endpoints também facilita a expansão do filtro sem a responsabilidade de intervir nas implementações dos endpoints de forma ativa. + ## Movendo as constantes para variáveis de ambiente Conforme mencionamos na aula sobre os 12 fatores, é uma boa prática manter as constantes que podem mudar dependendo do ambiente em variáveis de ambiente. Isso torna o seu projeto mais seguro e modular, pois você pode alterar essas constantes sem ter que modificar o código-fonte. diff --git a/aulas/assets/07/query_strings_pydantic.png b/aulas/assets/07/query_strings_pydantic.png new file mode 100644 index 00000000..91c397d4 Binary files /dev/null and b/aulas/assets/07/query_strings_pydantic.png differ