Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send file in memory to API from Node Express

I've an API in Node and Express which is receiving a file from a the client (Postman in development) and I use multer to get the file in memory like this:

router.post('/api/v1/upload', contrl.upload, contrl.uploadFile);

and then in my controller:

exports upload = multer({ storage: multer.memoryStorage() }).single('file');

Now I can access the file with req.file.buffer, but then I want to send this same file to another API. I'm using request-promise-native so this would be something like this:

const rp = require('request-promise-native')

exports.uploadFile = (req, res) => {

  const options = {
    method: 'POST',
    uri: `${uri}`,
    form: {
      file: req.file.buffer
    }
  }

  rp(options)
    .then(parsedBody => {
      return res.status(201).send(parsedBody);
    })
    .catch(err => res.status(400).send(err));
}

I removed some other params for simplicity, but this is not working, probably because Node doesn´t know how to handle the info inside req.file.buffer.

EDIT. Ok after some tests I tried to make this work with a real file instead of using multer memoryStorage. So I got this:

exports upload = multer({ dest: 'uploads/' }).single('file');

to save the file to disk, and then

const request = require('request')

exports.uploadFile = (req, res) => {

  const formData = {
    file: fs.createReadStream('uploads/' + req.file.filename)
  }
  const options = {
    url: `${uri}`
    formData
  }

  request.post(options, (err, response, body) => {
    if (err) return res.status(400).send(err);
    return res.status(201).send(response);
  });
}

And it works! But then when I change to memoryStorage in multer and I use file: req.file.buffer instead, it does not work.

EDIT2: I also tried to send the file as a stream when in memory, so I tried this

const bufferStream = new stream.PassThrough();
bufferStream.end(req.file.buffer);

and then passing it in the formData with file: bufferStream but also not working.

How can I achieve this? Thanks

like image 668
David Avatar asked Nov 25 '25 20:11

David


1 Answers

I had the same problem a few times and always end up with a bad solution. thank you all for this post. Here is my solution with aixios in case someone can use it

//First use form-data
const FormData = require('form-data') ;
//use axios
const axios = require('axios') ;


//Note is very important passing contentType and filename 
//options
let form = new FormData() ;
//consider req.file is the file coming from multer
form.append('file',req.file.buffer,{
     contentType:req.file.mimetype,
     filename:req.file.originalname
  }) ;


//now do a post request with axios
// personally I like the use of async-await for promises but
//then() catch() will work just fine
let response = await axios.post('API_URL', form, {
  headers: form.getHeaders() 
});
// whatever you need with response ex.
console.log(response.data)
like image 183
Fidel Perez Avatar answered Nov 27 '25 09:11

Fidel Perez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!