使用Vandium简化Node.js AWS Lambda处理程序

学习如何使用Vandium这个开源npm模块,快速为Node.js应用程序添加验证和注入攻击保护,特别是在Amazon Web Services (AWS) Lambda环境中。在第一部分中,学习了如何使用Vandium包装AWS Lambda处理程序。处理程序本身由一系列嵌套的异步回调函数组成,用于从一个用户向另一个用户发送消息。

尽管这段代码是功能性的,但如果在未来添加新功能,可能不会那么容易维护。潜在问题出现的原因是代码结构开始呈现出Node.js世界中所谓的“回调地狱”。为了避免这种模式,JavaScript语言引入了Promises。

Promises的使用消除了回调地狱,同时提高了代码的可维护性和可测试性。让看看传统的Node.js回调模式:

doThisFirst('start', function(err, result) { if (err) { console.log(err); return; } doThisSecond(result.two, function(err, result) { if (err) { console.log(err); return; } doThisThird(result.three, function(err, result) { if (err) { console.log(err); return; } console.log('result:', result); }); }); });

上面的回调模式将被Promises替换,以同时减少代码量并提高代码的可读性。由于正在修改现有代码,不想改变库代码,可以使用优秀的bluebird库来“Promisify”代码。

现在,让看看如何将Promises应用于Lambda处理程序。

'use strict'; const vandium = require('vandium'); const bluebird = require('bluebird'); const tokenValidator = bluebird.promisifyAll(require('./lib/token-validator')); const db = bluebird.promisifyAll(require('./lib/db')); const msgService = bluebird.promisifyAll(require('./lib/messages')); exports.handler = vandium(function(event, context, callback) { return tokenValidator.validateTokenAsync(event.token) .then(function(result) { let senderId = result.userId; return db.userExistsAsync(event.userId) .then(function() { return msgService.sendAsync(senderId, event.userId, event.message); }); }) .then(function(result) { callback(null, 'ok'); }) .catch(function(err) { callback(err); }); });

与之前的Promise示例一样,代码更加扁平化,更容易理解,代码量也减少了。注意在初始的“tokenValidator”Promise之后有一个嵌套的Promise。这样做是因为需要在确定用户存在之后访问“senderId”。当嵌套Promises时,内部Promise实例的返回值将被路由到外部实例的下一个“then”。

但有一件事感觉不太对劲?—?在Lambda处理程序的末尾使用回调函数来指示成功或失败的执行。理想情况下,Lambda处理程序将支持Promise模式,并允许在处理程序的末尾简单地返回一个值,而不是使用笨拙的回调函数。不幸的是,Lambda处理程序不支持Promises,但vandium支持。

Vandium专注于减少需要维护的代码量,同时提供鲁棒性、安全性和功能性。当使用vandium时,Promises被视为一等公民。要使用此功能,只需返回Promise,vandium会为处理其余的事情。

当vandium包装处理程序时,它会自动将成功和失败的Promise路由到回调处理程序。这很重要,因为它消除了开发人员手动将值路由到Lambda回调函数的每个成功或失败案例的需要。自然地,这允许开发人员更多地专注于编写Lambda处理程序中需要执行的实际逻辑。

以下是“Promisified”Lambda处理程序,用vandium包装,返回值(或错误)自动路由到Lambda回调。

'use strict'; const vandium = require('vandium'); const bluebird = require('bluebird'); const tokenValidator = bluebird.promisifyAll(require('./lib/token-validator')); const db = bluebird.promisifyAll(require('./lib/db')); const msgService = bluebird.promisifyAll(require('./lib/messages')); exports.handler = vandium(function(event) { return tokenValidator.validateTokenAsync(event.token) .then(function(result) { let senderId = result.userId; return db.userExistsAsync(event.userId) .then(function() { return msgService.sendAsync(senderId, event.userId, event.message); }); }) .then(function() { return 'ok'; }); });

请注意,现在将Promise本身返回给vandium包装器。Vandium将负责确定Promise的结果。在成功完成的情况下,或者在错误的情况下,vandium将自动将任一结果的返回值路由回Lambda处理程序的回调函数。此外,代码通过移除不再需要的上下文和回调参数进一步简化。

从51行嵌套回调代码开始,现在只剩下不到40行代码,流程大大简化。代码行数更少,分支结构更简单,使得维护和测试更加容易。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485