Junta várias funções intermediárias numa só, que as roda em cadeia; cada uma recebe o contexto e um next que segue a cadeia. É o jeito comum de montar sistemas de middleware, ao estilo do Koa.
Argumento
Descrição
Tipo
Function
A função intermediária já composta
ComposedMiddleware<T>
Parâmetro
Descrição
Tipo
Padrão
middleware
Array de funções intermediárias
Array<Middleware<T>>
Obrigatório
type Middleware < T > = ( context : T , next : Next ) => any ;
type Next = () => Promise < never > | Promise < void >;
import { compose } from 'ranuts' ;
const middleware1 = async ( ctx , next ) => {
console. log ( 'Middleware 1: entra' );
await next ();
console. log ( 'Middleware 1: sai' );
};
const middleware2 = async ( ctx , next ) => {
console. log ( 'Middleware 2: entra' );
await next ();
console. log ( 'Middleware 2: sai' );
};
const middleware3 = async ( ctx , next ) => {
console. log ( 'Middleware 3: executa' );
ctx.data = 'Processado' ;
};
const composed = compose ([middleware1, middleware2, middleware3]);
const context = {};
await composed (context);
// Saída:
// Middleware 1: entra
// Middleware 2: entra
// Middleware 3: executa
// Middleware 2: sai
// Middleware 1: sai
console. log (context.data); // 'Processado'
import { compose } from 'ranuts' ;
// Middleware de registro
const logger = async ( req , next ) => {
console. log ( `[${ new Date (). toISOString () }] ${ req . method } ${ req . url }` );
await next ();
};
// Middleware de autenticação
const auth = async ( req , next ) => {
if ( ! req.headers.authorization) {
throw new Error ( 'Não autorizado' );
}
await next ();
};
// Middleware que atende a requisição
const handler = async ( req , next ) => {
req.response = { message: 'Hello World' };
};
const app = compose ([logger, auth, handler]);
const request = {
method: 'GET' ,
url: '/api/users' ,
headers: { authorization: 'Bearer token123' },
};
await app (request);
console. log (request.response); // { message: 'Hello World' }
import { compose } from 'ranuts' ;
const errorHandler = async ( ctx , next ) => {
try {
await next ();
} catch (error) {
console. error ( 'Error:' , error.message);
ctx.error = error;
}
};
const handler = async ( ctx , next ) => {
throw new Error ( 'O processamento falhou' );
};
const composed = compose ([errorHandler, handler]);
const context = {};
await composed (context);
console. log (context.error); // Error: O processamento falhou
Ordem de execução : os middleware rodam na ordem do array, e o seguinte entra depois da chamada a next().
Com async : todos os middleware devem ser funções assíncronas ou devolver promessas.
A chamada a next() : é preciso chamar next() dentro do middleware para seguir ao próximo.
Chamadas repetidas : não dá para chamar next() mais de uma vez; se chamar, um erro é lançado.
O contexto : os dados passam de um middleware a outro pelo objeto context.