-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Consider a remotable method that returns a stream as the result, for example "download file" in loopback-storage-service (source).
The current implementation takes the response object as an argument and does not call the provided callback. This means that "after" hooks are never called. (remoting metadata).
File.download = function(file, res, cb) {
var reader = fs.createReadStream('storage/' + file);
reader.on('error', function (err) {
res.type('application/json');
res.send(500, { error: err });
});
reader.pipe(res);
// callback is intentionally not invoked
};
File.remoteMethod('download', {
accepts: [
{arg: 'file', type: 'string', 'http': {source: 'path'}},
{arg: 'res', type: 'object', 'http': {source: 'res'}}
],
http: {
verb: 'get',
path: '/download/:file'
}
});We should make streams a first-class citizen in strong-remoting.
HttpContext.prototype.invoke seems to already support piping a stream provided by the remotable method to the HTTP response (source).
Tasks
- implementation in strong-remoting - see Stream as an accepts/returns argument strong-remoting#35 and Add support for "file" return args strong-remoting#284
- support in loopback-swagger - see Support the new return arg type "file" loopback-swagger#34
- documentation - see Doc: return response body from remote method #2209
A note for loopback-swagger support. Swagger spec says: http://swagger.io/specification/#responseObject
As an extension to the Schema Object, its root type value may also be "file". This SHOULD be accompanied by a relevant produces mime-type.
I don't remember whether loopback-swagger supports per-method produces option. If it does not, then we should implement it as part of this work.