nocobase/docs/en-US/development/server/middleware.md

161 lines
3.6 KiB
Markdown
Raw Normal View History

2022-11-06 05:48:06 +00:00
# Middleware
2022-11-06 05:48:06 +00:00
## How to register middleware?
2022-11-06 05:48:06 +00:00
The registration method for middleware is usually written in the load method
```ts
export class MyPlugin extends Plugin {
load() {
this.app.acl.use();
this.app.resourcer.use();
this.app.use();
}
}
```
2022-11-06 05:48:06 +00:00
Notes.
2022-11-06 05:48:06 +00:00
1. `app.acl.use()` Add a resource-permission-level middleware to be executed before permission determination
2. `app.resourcer.use()` Adds a resource-level middleware that is executed only when a defined resource is requested
3. `app.use()` Add an application-level middleware to be executed on every request
2022-11-06 05:48:06 +00:00
## Onion Circle Model
```ts
app.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(1);
await next();
ctx.body.push(2);
});
app.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(3);
await next();
ctx.body.push(4);
});
```
2022-11-06 05:48:06 +00:00
Visit http://localhost:13000/api/hello to see that the browser responds with the following data
```js
{"data": [1,3,4,2]}
```
2022-11-06 05:48:06 +00:00
## Built-in middlewares and execution order
1. `cors`
2. `bodyParser`
3. `i18n`
4. `dataWrapping`
2022-11-06 05:48:06 +00:00
5. `db2resource` 6.
6. `restApi` 1.
1. `parseToken` 2.
2. `checkRole`
2022-11-06 05:48:06 +00:00
3. `acl` 1.
1. `acl.use()` Additional middleware added
4. `resourcer.use()` Additional middleware added
5. `action handler`
7. `app.use()` Additional middleware added
2022-11-06 05:48:06 +00:00
You can also use `before` or `after` to insert the middleware into the location of one of the preceding `tag`, e.g.
```ts
app.use(m1, { tag: 'restApi' });
app.resourcer.use(m2, { tag: 'parseToken' });
app.resourcer.use(m3, { tag: 'checkRole' });
2022-11-06 05:48:06 +00:00
// m4 will come before m1
app.use(m4, { before: 'restApi' });
2022-11-06 05:48:06 +00:00
// m5 will be inserted between m2 and m3
app.resourcer.use(m5, { after: 'parseToken', before: 'checkRole' });
```
2022-11-06 05:48:06 +00:00
If no location is specifically specified, the order of execution of the added middlewares is
2022-11-06 05:48:06 +00:00
1. middlewares added by `acl.use` will be executed first
2. then the ones added by `resourcer.use`, including the middleware handler and action handler
3. and finally the ones added by `app.use`
```ts
app.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(1);
await next();
ctx.body.push(2);
});
app.resourcer.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.resourcer.define({
name: 'test',
actions: {
async list(ctx, next) {
ctx.body = ctx.body || [];
ctx.body.push(7);
await next();
ctx.body.push(8);
},
},
});
```
2022-11-06 05:48:06 +00:00
Visit http://localhost:13000/api/hello to see that the browser responds with the data
```js
{"data": [1,2]}
```
2022-11-06 05:48:06 +00:00
Visiting http://localhost:13000/api/test:list to see, the browser responds with the following data
```js
{"data": [5,3,7,1,2,8,4,6]}
```
2022-11-06 05:48:06 +00:00
### Resource undefined, middlewares added by resourcer.use() will not be executed
```ts
app.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(1);
await next();
ctx.body.push(2);
});
app.resourcer.use(async (ctx, next) => {
ctx.body = ctx.body || [];
ctx.body.push(3);
await next();
ctx.body.push(4);
});
```
2022-11-06 05:48:06 +00:00
Visit http://localhost:13000/api/hello to see that the browser responds with the following data
```js
{"data": [1,2]}
```
2022-11-06 05:48:06 +00:00
In the above example, the hello resource is not defined and will not enter the resourcer, so the middleware in the resourcer will not be executed
2022-11-06 05:48:06 +00:00
## Middleware Usage
2022-11-06 05:48:06 +00:00
TODO
2022-11-06 05:48:06 +00:00
## Example
- [samples/ratelimit](https://github.com/nocobase/nocobase/blob/main/packages/samples/ratelimit/) IP rate-limiting