Boas práticas e padrões · Padrões comportamentais · 4 min de leitura
Chain of Responsibility
A requisição passa por uma corrente de manipuladores; cada um trata, altera ou repassa — como os middlewares de uma API.
Arraste para o lado para ver o diagrama inteiro.
Onde aparece
Middlewares do Express e do Ktor, interceptors do OkHttp, filtros do Spring, o sistema de eventos do DOM (propagação) e pipelines de aprovação ("acima de R$ 10 mil vai para o diretor").
Cuidados
- A ordem importa: autenticação antes do rate limit por usuário.
- Garanta um fim: se ninguém tratar, responda algo útil.
- Corrente longa é difícil de depurar — registre por onde a requisição passou.
No código
type Handler = (req: Req, next: () => Promise<Res>) => Promise<Res>;
const auth: Handler = async (req, next) => (req.user ? next() : { status: 401 });
const rateLimit: Handler = async (req, next) => ((await limiter.allow(req.user!.id)) ? next() : { status: 429 });
const validate: Handler = async (req, next) => (isValid(req.body) ? next() : { status: 400 });
function chain(handlers: Handler[], final: (req: Req) => Promise<Res>) {
return (req: Req) => {
const run = (i: number): Promise<Res> => (i === handlers.length ? final(req) : handlers[i]!(req, () => run(i + 1)));
return run(0);
};
}
export const criarPedido = chain([auth, rateLimit, validate], (req) => pedidos.criar(req.body)); Cada regra é uma função pequena e testável; uma regra nova (log, idempotência) entra na lista sem tocar nas outras.
Em resumo
- Cada elo trata ou repassa.
- Remetente não sabe quem vai tratar.
- Middlewares e interceptors são o exemplo clássico.
- Ordem e um final garantido importam.