Handler é um conceito central do framework Salvo, que pode ser entendido como uma unidade de processamento de requisições, com dois principais usos:
Como Endpoint: Objetos que implementam Handler
podem ser colocados no sistema de roteamento como pontos finais de processamento. Ao usar a macro #[handler]
, funções podem ser usadas diretamente como endpoints; já com a macro #[endpoint]
, além de servir como endpoint, também geram automaticamente documentação OpenAPI (detalhada em documentação posterior).
Como Middleware: O mesmo Handler
pode atuar como middleware, processando requisições antes ou depois de chegarem ao endpoint final.
O fluxo de processamento do Salvo funciona como um "pipeline": requisições passam primeiro por uma série de middlewares (processamento vertical) antes de alcançar o endpoint correspondente (processamento horizontal). Tanto middlewares quanto endpoints são implementações de Handler
, garantindo consistência e flexibilidade ao sistema.
A essência do modelo cebola está no posicionamento de ctrl.call_next()
, que permite o processamento bidirecional (requisição e resposta), fazendo com que cada middleware participe de todo o ciclo.
Handler é o objeto responsável por processar requisições. É um Trait que contém um método assíncrono handle
:
O método handle
recebe quatro parâmetros: &mut Request, &mut Depot, &mut Response, &mut FlowCtrl
. Depot é um armazenamento temporário para dados da requisição.
Dependendo do uso, pode servir como middleware (hoop), processando requisições antes ou depois do Handler principal (ex: autenticação, compressão).
Middlewares são adicionados via função hoop
do Router
e afetam o Router
atual e seus descendentes.
Handlers também podem ser usados como endpoints finais (goal).
Como middleware, pode ser adicionado a três tipos de objetos:
Service
: Todas as requisições passam por seus middlewares.Router
: Somente requisições com rota correspondente.Catcher
: Acionado quando ocorrem erros não tratados.Handler
: Permite adicionar middlewares para lógica pré/pós-processamento.#[handler]
#[handler]
simplifica código e aumenta flexibilidade:
Equivale a:
Vantagens:
#[async_trait]
.Writer
/Scribe
podem ser retornados diretamente.Também pode ser usada em impl
para structs:
Handlers podem retornar Result
, desde que Ok
e Err
implementem Writer
. Com o recurso anyhow
ativado, anyhow::Error
implementa Writer
e mapeia para InternalServerError
.
Para erros personalizados: