3

I am currently trying to produce an API using loopback that allows me to send a 28x28 image file of a handwritten character and have the image processed by a tensorflow network and return the prediction of what the network thinks the character is.

In order to do this, however, I need to be able to send the image to be processed without having to save the file on the server first and cannot find how to do such a thing. Modules such as loopback-component-storage are great, but I do not want to have to use one route to send the image, another to process that image, and then a third to then remove the container containing that image file, making the process require three different requests.

Hence it comes down to this, is there any way that I can attach an image to the request where the stream can be read and interpreted by the API without having to first save a copy of the file somewhere else on the server?

Thanks in advance

Glenn Keates
  • 121
  • 8
  • When you are talking about uploading a file, do you meant to upload it as if it was sent from an HTML form (input type=file) - i.e. as one of the possibly many multipart entries, or can you send the image payload directly in the request body as the only data sent to the server? – Miroslav Bajtoš Oct 26 '18 at 13:58
  • I wanted to send the image file directly in the request body. this is so that I could pass it to an instance of the Image class where I could set the source of the image to the file included in the request – Glenn Keates Nov 09 '18 at 15:05

1 Answers1

5

I am recommending the following solution:

First, configure your server middleware to parser image request bodies:

  1. Install body-parser dependency.

    $ npm install --save body-parser
    
  2. Configure the raw parser by adding the following content to parse section of your server/middleware.json file:

    {
      "body-parser#raw": {
        "limit": "100kb",
        "type": "image/*"
      }
    }
    

    The "limit" option sets the maximum allowed request body size. You don't want to allow arbitrary size to prevent malicious clients from crashing your server on "out of memory" error.

    The "type" option configures content-types that should be parsed by this middleware. In my example above, I am allowing all image types.

Next, implement a remote method accepting the request body. Thanks to the raw body parser, the body stream will be already converted into a Buffer for you. In my example below, I have a simple method that responds with a base64-encoded body.

module.exports = function(Image) {
  Image.analyze = async function(data) {
    // Reject non-image requests, e.g. JSON
    if (!Buffer.isBuffer(data)) {
      const err = new Error('Unsupported media type'); 
      err.statusCode = 415;
      throw err;
    }

    // data is a Buffer containing the request body
    return data.toString('base64');
  };

  Image.remoteMethod('analyze', {
    accepts: [
      // {source: 'body'} is the important part
      {arg: 'data', type: 'object', http: {source: 'body'}},
    ],
    returns: {root: true, type: 'string'},
    http: {path: '/analyze', verb: 'post'},
  });
};
Miroslav Bajtoš
  • 10,667
  • 1
  • 41
  • 99