为快速路由器创建装饰器?
Creating decorators for express router?
为了使代码更加轻量和可读,我想到了为 express router 创建一个简单的装饰器。
发件人:
itemRouter
.get('/:item_id', async (req, res, next) => {
try {
const id = parseInt(req.params.item_id)
const item = await itemController.getItemById(id)
res.status(StatusCodes.OK).send(item)
} catch (error) {
next(error)
}
})
接近这个最终结果的东西:
itemRouter
.get('/:item_id',
expressDecorator(async (req, res, next) => {
const id = parseInt(req.params.item_id)
return itemController.getItemById(id)
})
})
function expressDecorator(wrapped) {
return function () {
const { req, res, next } = arguments
try {
const { statusCode, bodyResponse } = wrapped.apply(this, arguments)
res.status(statusCode).send(bodyResponse)
} catch (error) {
next(error)
}
}
}
但是我遗漏了一些东西,因为它根本不起作用。这是什么?
PS : 我完全知道有一个 express-router-decorator npm 包,但我希望自己做实验来了解它是如何工作的。
您原来的路由器控制器使用 async/await
语法。内部函数也应该使用 async/await
。
例如
const express = require('express');
const app = express();
const port = 3000;
const itemController = {
getItemById(id) {
return { statusCode: 200, bodyResponse: 'test_item_' + id };
},
};
app.get(
'/:item_id',
expressDecorator(async (req, res, next) => {
const id = parseInt(req.params.item_id);
return itemController.getItemById(id);
}),
);
function expressDecorator(wrapped) {
return async function (...args) {
const [req, res, next] = args;
try {
const { statusCode, bodyResponse } = await wrapped.apply(this, args);
res.status(statusCode).send(bodyResponse);
} catch (error) {
next(error);
}
};
}
app.listen(port, () => console.log(`HTTP server started at http://localhost:${port}`));
测试通过 curl
:
> curl http://localhost:3000/1
StatusCode : 200
StatusDescription : OK
Content : test_item_1
RawContent : HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: timeout=5
Content-Type: text/html; charset=utf-8
Date: Wed, 03 Feb 2021 02:32:02 GMT
ETag: W/"b-UjEymk+xUeSCTPOQ7NOHrxuV2as"...
Forms : {}
Headers : {[Connection, keep-alive], [Keep-Alive, timeout=5], [Co
ntent-Length, 11], [Content-Type, text/html; charset=ut
f-8]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : System.__ComObject
为了使代码更加轻量和可读,我想到了为 express router 创建一个简单的装饰器。
发件人:
itemRouter
.get('/:item_id', async (req, res, next) => {
try {
const id = parseInt(req.params.item_id)
const item = await itemController.getItemById(id)
res.status(StatusCodes.OK).send(item)
} catch (error) {
next(error)
}
})
接近这个最终结果的东西:
itemRouter
.get('/:item_id',
expressDecorator(async (req, res, next) => {
const id = parseInt(req.params.item_id)
return itemController.getItemById(id)
})
})
function expressDecorator(wrapped) {
return function () {
const { req, res, next } = arguments
try {
const { statusCode, bodyResponse } = wrapped.apply(this, arguments)
res.status(statusCode).send(bodyResponse)
} catch (error) {
next(error)
}
}
}
但是我遗漏了一些东西,因为它根本不起作用。这是什么?
PS : 我完全知道有一个 express-router-decorator npm 包,但我希望自己做实验来了解它是如何工作的。
您原来的路由器控制器使用 async/await
语法。内部函数也应该使用 async/await
。
例如
const express = require('express');
const app = express();
const port = 3000;
const itemController = {
getItemById(id) {
return { statusCode: 200, bodyResponse: 'test_item_' + id };
},
};
app.get(
'/:item_id',
expressDecorator(async (req, res, next) => {
const id = parseInt(req.params.item_id);
return itemController.getItemById(id);
}),
);
function expressDecorator(wrapped) {
return async function (...args) {
const [req, res, next] = args;
try {
const { statusCode, bodyResponse } = await wrapped.apply(this, args);
res.status(statusCode).send(bodyResponse);
} catch (error) {
next(error);
}
};
}
app.listen(port, () => console.log(`HTTP server started at http://localhost:${port}`));
测试通过 curl
:
> curl http://localhost:3000/1
StatusCode : 200
StatusDescription : OK
Content : test_item_1
RawContent : HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: timeout=5
Content-Type: text/html; charset=utf-8
Date: Wed, 03 Feb 2021 02:32:02 GMT
ETag: W/"b-UjEymk+xUeSCTPOQ7NOHrxuV2as"...
Forms : {}
Headers : {[Connection, keep-alive], [Keep-Alive, timeout=5], [Co
ntent-Length, 11], [Content-Type, text/html; charset=ut
f-8]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : System.__ComObject