6.1 KiB
Remote methods and hooks
You can expose a Model's instance and static methods to clients. A remote method must accept a callback with the conventional fn(err, result, ...)
signature.
loopback.remoteMethod(fn, [options])
Expose a remote method.
Product.stats = function(fn) {
var statsResult = {
totalPurchased: 123456
};
var err = null;
// callback with an error and the result
fn(err, statsResult);
}
loopback.remoteMethod(
Product.stats,
{
returns: {arg: 'stats', type: 'object'},
http: {path: '/info', verb: 'get'}
}
);
Options
The options argument is a JSON object, described in the following table.
Option | Required? | Description |
---|---|---|
accepts | No | Describes the remote method's arguments, as explained below. The callback is an assumed argument; do not specify. |
returns | No | Describes the remote method's callback arguments, as explained below.. The err argument is assumed; do not specify. |
http | No | HTTP routing information:
|
The arguments description defines either a single argument as an object or an ordered set of arguments as an array. Each individual argument has keys for:
- arg: argument name
- type: argument datatype; must be aloopback type.
- required: Boolean value indicating if argument is required.
- root: For callback arguments: set this property to true if your function has a single callback argument that should be used as the root object returned to remote caller. Otherwise a map (argument-name to argument-value) is returned.
- http: For input arguments: a function or an object describing mapping from HTTP request to the argument value, as explained below.
For example, a single argument, specified as an object:
{arg: 'myArg', type: 'number'}
Multiple arguments, specified as an array:
[
{arg: 'arg1', type: 'number', required: true},
{arg: 'arg2', type: 'array'}
]
HTTP mapping of input arguments
There are two ways how to specify HTTP mapping for input parameters (what the method accepts).
The first way is to provide an object with a source
property, that can have
one of these values:
source | description |
---|---|
body | The whole request body is used as the value. |
form | The value is looked up using req.param , which searches route arguments, the request body and the query string. |
query | An alias for form (see above). |
path | An alias for form (see above). |
req | The whole HTTP reqest object is used as the value. |
For example, an argument getting the whole request body as the value:
{ arg: 'data', type: 'object', http: { source: 'body' } }
The second way is to specify your custom mapping function:
{
arg: 'custom',
type: 'number',
http: function(ctx) {
// ctx is LoopBack Context object
// 1. Get the HTTP request object as provided by Express
var req = ctx.req;
// 2. Get 'a' and 'b' from query string or form data
// and return their sum as the value
return +req.param('a') + req.param('b');
}
}
When there is no mapping specified, LoopBack will look up the value
using the following algorithm (assuming name
as the name of the input
parameter to resolve):
- If there is a HTTP request parameter
args
with a JSON content, then its content is parsed and the value ofargs['name']
is used if it is defined. - Otherwise
req.param('name')
is returned.
Remote hooks
Run a function before or after a remote method is called by a client.
// *.save === prototype.save
User.beforeRemote('*.save', function(ctx, user, next) {
if(ctx.user) {
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();
});
Remote hooks also support wildcards. Run a function before any remote method is called.
// ** will match both prototype.* and *.*
User.beforeRemote('**', function(ctx, user, next) {
console.log(ctx.methodString, 'was invoked remotely'); // users.prototype.save was invoked remotely
next();
});
Other wildcard examples
// run before any static method eg. User.find
User.beforeRemote('*', ...);
// run before any instance method eg. User.prototype.save
User.beforeRemote('prototype.*', ...);
// prevent password hashes from being sent to clients
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
Remote hooks are provided with a Context ctx
object which contains transport specific data (eg. for http: req
and res
). The ctx
object also has a set of consistent apis across transports.
ctx.user
A Model
representing the user calling the method remotely. Note: this is undefined if the remote method is not invoked by a logged in user.
ctx.result
During afterRemote
hooks, ctx.result
will contain the data about to be sent to a client. Modify this object to transform data before it is sent.
Rest
When loopback.rest is used the following ctx
properties are available.
ctx.req
The express ServerRequest object. See full documentation.
ctx.res
The express ServerResponse object. See full documentation.