REVIEW COMMENT from Rand
See issue #800
See issue #800
概要
LoopBack提供两种类型的钩子:
- Remote钩子, 在远程方法被调用的前后执行。
- Model 钩子, 在模型方法被调用的前后执行。
远程钩子使得你可以在一个远程方法被调用的前后之行一个函数:
beforeRemote()
在远程方法被调用前之行。afterRemote()
在远程方法被调用后之行。
签名
beforeRemote()
和 afterRemote() 有同样的签名;
modelName.beforeRemote( methodName, function( ctx, modelInstance, next) {
...
next();
}
...
next();
}
modelName
是模型的名字。methodName
是远程方法名。可以是一个自定义的远程方法 也可以是一个继承自PersistedModel 的标准CRUD方法。可以包含通配符去匹配多个方法(见下)。ctx
是一个 context object.modelInstance
是受影响的模型实例。
在methodName中使用星号 '*'匹配任何字符。使用
'*.*' 匹配任意静态方法
; 使用 'prototype.*'匹配任意实例方法。
上面的例子包含一个next()的调用。 你必须在你的钩子回调方法里面调用next()。 你可以不在函数的最后调用next(), 但是你必须调用next(), 不管你是在回调函数的开始、中间、最后调用。
例子
下面的例子定义了一个远程钩子在远程方法count()执行后被调用:
/common/models/model.js
var request = require('request'); Users.afterRemote('count', function(ctx, affectedModelInstance, next) { request.post({ url: 'http://another.server.com/', method: 'POST', json: ctx.result }, function(err, response) { if (err) console.error(err); next(); }); });
下面的例子在方法名中使用了通配符。当任何以"save"结尾的远程方法被调用被执行:
/common/models/model.js
User.beforeRemote('*.save', function(ctx, unused, next) { if(ctx.req.accessToken) { next(); } else { next(new Error('must be logged in to update')) } }); User.afterRemote('*.save', function(ctx, user, next) { console.log('user has been saved', user); next(); });
下面的例子, 在任何远程方法执行前被调用:
/common/models/model.js
// ** 匹配prototype.* 和 *.* User.beforeRemote('**', function(ctx, user, next) { console.log(ctx.methodString, 'was invoked remotely'); // users.prototype.save was invoked remotely next(); }); Other wildcard examples // 在任何静态方法前执行 User.beforeRemote('*', ...); // 在任何实例方法前执行 User.beforeRemote('prototype.*', ...); // 防止用户密码被发送给客户端 User.afterRemote('**', function (ctx, user, next) { if(ctx.result) { if(Array.isArray(ctx.result)) { ctx.result.forEach(function (result) { result.password = undefined; }); } else { ctx.result.password = undefined; } } next(); });
Context对象
远程钩子提供了一个上下文对象 ctx
,它包含了transport-specific 数据 (HTTP: req
和 res
). The ctx
object also has a set of consistent APIs across transports.
Applications that use loopback.rest() middleware provide the following additional ctx
properties:
ctx.req.accessToken
用户调用远程方法使用的accessToken
。
ctx.result
对于afterRemote
钩子, ctx.result包含了发送给客户端的data。
在发送数据给客户端之前可以修改这个对象。