How can I use body-parser with LoopBack?

前端 未结 8 661
别那么骄傲
别那么骄傲 2020-12-24 13:56

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 middlewar

相关标签:
8条回答
  • 2020-12-24 14:35

    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!

    0 讨论(0)
  • 2020-12-24 14:36

    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."})
        });
    }
    
    0 讨论(0)
  • 2020-12-24 14:37

    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.

    0 讨论(0)
  • 2020-12-24 14:41

    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.

    0 讨论(0)
  • 2020-12-24 14:41

    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());

    0 讨论(0)
  • 2020-12-24 14:46

    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",
    
    0 讨论(0)
提交回复
热议问题