How can I use body-parser with LoopBack?

醉酒当歌 提交于 2019-12-18 11:07:03

问题


I see that LoopBack has the Express 3.x middleware built-in. Indeed, body-parser is in loopback/node_modules. But I cannot figure out how to use it as middleware. I have never worked with Express 3.x, so maybe it's just that. require does not work, obviously, unless I install body-parser as a dependency in my project.

What should I do in server.js to use body-parser so that web forms are parsed into req.params? That's what it does, right?


回答1:


After hours of frustration, I just added it to middleware.json like so:

"parse": {
    "body-parser#json": {},
    "body-parser#urlencoded": {"params": { "extended": true }}
}

It is installed as a dependency. Now I have form data in req.body in my routes. My server/boot/routes.js looks like this:

module.exports = function(app) {
    app.post('/mailing_list', function(req, res) {
        console.log(req.body.email);
        res.send({"status": 1, "message": "Successfully added to mailing list."})
    });
}



回答2:


Just to be more clear about what it takes to get this working (because I still struggled for a while after finding this answer!), here are the steps I took:

As described above, in $APP_HOME/server/middleware.json, add the body-parser to the "parse" section:

{
  "initial:before": {
    "loopback#favicon": {}
  },
  "initial": {
    "compression": {},
    "cors": {
      "params": {
        "origin": true,
        "credentials": true,
        "maxAge": 86400
      }
    }
  },
  "session": {
  },
  "auth": {
  },
  "parse": {
    "body-parser#json": {},
    "body-parser#urlencoded": {"params": { "extended": true }}
  },
  "routes": {
  },
  "files": {
  },
  "final": {
    "loopback#urlNotFound": {}
  },
  "final:after": {
    "errorhandler": {}
  }
}

Next, I added the parser setup to $APP_HOME/server/server.js:

var loopback = require('loopback');
var bodyParser = require('body-parser');
var multer = require('multer');

var boot = require('loopback-boot');

var app = module.exports = loopback();

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(multer()); // for parsing multipart/form-data

app.start = function() {
...
...
cont'd

Then, since I didn't want to mess with custom routes, I added the following to $APP_HOME/common/models/model.js:

module.exports = function(Model) {

  Model.incoming = function(req, cb) {
    cb(null, 'Hey there, ' + req.body.sender);
  }
  Model.remoteMethod(
    'incoming',
    { accepts: [
      { arg: 'req', type: 'object', http: function(ctx) {
        return ctx.req;
      } 
    }],
    returns: {arg: 'summary', type: 'string'}
    }
  );
};

I can now run my app with $> slc run .

When I post to the endpoint, it now gets parsed properly, and all is well with the world. I hope this helps someone else!




回答3:


I'm using loopback 2.14.0:

To make use of the body-parser in your custom bootscript routes you should only need to:

1) install body-parser npm install body-parser --save

2) Register the the module in middleware.json

"parse": {
"body-parser#json": {},
"body-parser#urlencoded": {"params": { "extended": true }}
},

There is no need to require the parser setup in server.js, loopback does this for you when you register the middleware.

Please note body parser is now installed in your source "node_modules" directory as well as in the loopback modules directory.

If at all possible try register custom remote methods as described in the loopback documentation.

Registering routes this way gives you access to loopback's body-parser out of the box and is the 'cleanest' implementation.




回答4:


Based on this answer https://stackoverflow.com/a/29813184/605586 from Ben Carlson you have to

npm install --save body-parser multer

then in your server.js require the modules:

var bodyParser = require('body-parser');
var multer = require('multer');

and use them before app.start:

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(multer().any()); // for parsing multipart/form-data

Then you can create a remote method:

App.incoming = function (req, cb) {
    console.log(req);
    // the files are available as req.files.
    // the body fields are available in req.body
    cb(null, 'Hey there, ' + req.body.sender);
}
App.remoteMethod(
    'incoming',
    {
    accepts: [
        {
        arg: 'req', type: 'object', http: function (ctx) {
            return ctx.req;
        }
        }],
    returns: { arg: 'summary', type: 'string' }
    }
);

Using this you can upload files and additional data fields to loopback with multipart/form-data.




回答5:


I'm posting this just for informational purposes. I ran into this same issue and found this works as well. You can add a file in the server/boot/ directory with the following:

var bodyParser = require('body-parser');

module.exports = function(app) {
  app.use(bodyParser.urlencoded({ extended: true }));
}

Of course, you have to install the package by running:

npm install --save body-parser

That will save the package under the node_modules directory. If you want it to be the first thing to run, you can start the file name with a "0" since these are loaded in alphabetical order.

That being said, I figure it is more 'correct' and elegant to use the middleware configuration approach mentioned above than this one, but I share it in the event someone else finds it useful.




回答6:


In Loopback ^3.22.0, I can suffice by adding the

"parse": {
    "body-parser#json": {}
  },

to the server/middleware.json in order to consume application/json post bodies in the server/boot/routes.js

module.exports = function(app) {
  app.post('/api/sayhello', function(req, res, next) {
     console.log(req.body)



回答7:


I have different test result.

1) For json and urlencode types, there is NO need to add their parser in middleware.json. I can get data from req.body successfully without adding body-parser#json and body-parser#urlencoded. The Loopback should already support them.

Loopback related source code(I think)

1. in strong-remote repo , rest-adapter.js , there is body-parser for json and urlendcoded

line 35
var json = bodyParser.json;
var urlencoded = bodyParser.urlencoded;

line 315
root.use(urlencoded(urlencodedOptions));
root.use(json(jsonOptions));

2. 
remote-object.js
line 33
require('./rest-adapter');

line 97
RemoteObjects.prototype.handler = function(nameOrClass, options) {
var Adapter = this.adapter(nameOrClass);
var adapter = new Adapter(this, options);
var handler = adapter.createHandler();

if (handler) {
// allow adapter reference from handler
handler.adapter = adapter;
}

return handler;
};

2) For the raw type, we can add body-parser#raw in "parse" part in middleware.json , of course, it needs to npm install body-parser.

My test code :

1.My readable stream is from the file uploadRaw.txt , the content is :
GreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaEeeeend

2. middleware.json
"parse": {
"body-parser#raw": {
"paths": [
"/api/v1/Buckets/?/upload"
]
}
},

3.
it('application/octet-stream -- upload non-form', () =>
new Promise((resolve) => {

const options = {

method: 'POST',

host: testConfig.server.host,

port: testConfig.server.port,

path: ${appconfig.restApiRoot}/Buckets/${TEST_CONTAINER}/upload,

headers: {

'Content-Type': 'application/octet-stream',

},
};

const request = http.request(options);

request.on('error', (e) => {
logger.debug(problem with request: ${e.message});
});

const readStream = fs.createReadStream('tests/resources/uploadRaw.txt');

readStream.pipe(request);

resolve();
}));

4.
Bucket.upload = (req, res, options, cb) => {

logger.debug('sssssss in uploadFileToContainer');

fs.writeFile('/Users/caiyufei/TEA/green.txt', req.body, (err) => {

if (err) {

logger.debug('oh, failed to write file');

return;
}

logger.debug('green file is saved!');
});

};

OR

Bucket.upload = (req, res, options, cb) => {

logger.debug('sssssss in uploadFileToContainer');

const writeStream = fs.createWriteStream('/Users/caiyufei/TEA/green.txt');

const streamOptions = {
highWaterMark: 16384,`enter code here`
encoding: null,
}

streamifier.createReadStream(Buffer.from(req.body), streamOptions).pipe(writeStream);

};

5. package.json

"body-parser": "^1.17.1",

"streamifier": "^0.1.1",



回答8:


One could also use the built-in parser of express framework inside loopback like this, for example for json parsing: app.use(app.loopback.json());



来源:https://stackoverflow.com/questions/28523782/how-can-i-use-body-parser-with-loopback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!