Aviso de tradução por IA
Esta documentação foi traduzida automaticamente por IA.
Middleware
O middleware do NocoBase Server é essencialmente um middleware Koa. Você pode manipular o objeto ctx para lidar com requisições e respostas, assim como faria no Koa. No entanto, como o NocoBase precisa gerenciar a lógica em diferentes camadas de negócio, agrupar todo o middleware em um só lugar tornaria a manutenção e o gerenciamento muito difíceis.
Por isso, o NocoBase divide o middleware em quatro níveis:
-
Middleware de Nível de Fonte de Dados: app.dataSourceManager.use()
Afeta apenas requisições para uma fonte de dados específica, sendo comumente usado para lógica de conexão de banco de dados, validação de campos ou processamento de transações para essa fonte de dados.
-
Middleware de Nível de Recurso: app.resourceManager.use()
É eficaz apenas para recursos (Resource) definidos, sendo adequado para lidar com lógica de nível de recurso, como permissões de dados, formatação, etc.
-
Middleware de Nível de Permissão: app.acl.use()
Executa antes das verificações de permissão, usado para verificar permissões ou funções de usuário.
-
Middleware de Nível de Aplicação: app.use()
Executa para cada requisição, sendo adequado para registro de logs, tratamento geral de erros, processamento de respostas, etc.
Registro de Middleware
O middleware é geralmente registrado no método load do plugin, por exemplo:
export class MyPlugin extends Plugin {
load() {
// Middleware de nível de aplicação
this.app.use(async (ctx, next) => {
console.log('App middleware');
await next();
});
// Middleware de fonte de dados
this.app.dataSourceManager.use(async (ctx, next) => {
console.log('DataSource middleware');
await next();
});
// Middleware de permissão
this.app.acl.use(async (ctx, next) => {
console.log('ACL middleware');
await next();
});
// Middleware de recurso
this.app.resourceManager.use(async (ctx, next) => {
console.log('Resource middleware');
await next();
});
}
}
Ordem de Execução
A ordem de execução do middleware é a seguinte:
- Primeiro, executa o middleware de permissão adicionado por
acl.use().
- Em seguida, executa o middleware de recurso adicionado por
resourceManager.use().
- Depois, executa o middleware de fonte de dados adicionado por
dataSourceManager.use().
- Por fim, executa o middleware de aplicação adicionado por
app.use().
Mecanismo de Inserção before / after / tag
Para um controle mais flexível da ordem do middleware, o NocoBase oferece os parâmetros before, after e tag:
- tag: Atribui uma marca a um middleware, para que possa ser referenciado por middleware subsequente.
- before: Insere antes do middleware com a tag especificada.
- after: Insere depois do middleware com a tag especificada.
Exemplo:
// Middleware comum
app.use(m1, { tag: 'restApi' });
app.resourceManager.use(m2, { tag: 'parseToken' });
app.resourceManager.use(m3, { tag: 'checkRole' });
// m4 será posicionado antes de m1
app.use(m4, { before: 'restApi' });
// m5 será inserido entre m2 e m3
app.resourceManager.use(m5, { after: 'parseToken', before: 'checkRole' });
TIP
Se nenhuma posição for especificada, a ordem de execução padrão para o middleware recém-adicionado é:
acl.use() -> resourceManager.use() -> dataSourceManager.use() -> app.use()
Exemplo do Modelo de Camadas (Onion Model)
A ordem de execução do middleware segue o Modelo de Camadas (Onion Model) do Koa, ou seja, ele entra na pilha de middleware primeiro e sai por último.
app.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(1);
await next();
ctx.body.push(2);
});
app.resourceManager.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(3);
await next();
ctx.body.push(4);
});
app.acl.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(5);
await next();
ctx.body.push(6);
});
app.resourceManager.define({
name: 'test',
actions: {
async list(ctx, next) {
ctx.body = ctx.body || [];
ctx.body.push(7);
await next();
ctx.body.push(8);
},
},
});
Exemplos de ordem de saída ao acessar diferentes interfaces:
-
Requisição comum: /api/hello
Saída: [1,2] (recurso não definido, não executa o middleware resourceManager e acl)
-
Requisição de recurso: /api/test:list
Saída: [5,3,7,1,2,8,4,6]
O middleware executa de acordo com a ordem das camadas e o Modelo de Camadas (Onion Model).
Resumo
- O Middleware do NocoBase é uma extensão do Middleware Koa.
- Quatro níveis: Aplicação -> Fonte de Dados -> Recurso -> Permissão.
- Você pode usar
before / after / tag para controlar a ordem de execução de forma flexível.
- Segue o Modelo de Camadas (Onion Model) do Koa, garantindo que o middleware seja combinável e aninhável.
- O middleware de nível de fonte de dados afeta apenas requisições de fontes de dados especificadas, e o middleware de nível de recurso afeta apenas requisições de recursos definidos.