how to createWriteStream() to GCS?

Issue

I’m trying to write an Express route that takes an image URI in the POST body and then saves the image into a Google Cloud Storage Bucket.

I’m not able to persist this image to local disk and need to stream the buffer straight to the GCS bucket.

My route creates a 4KB "stub" in the GCS bucket but there’s no image payload. My nodejs then proceeds to crash…

Q: What is the correct way to .pipe() the results of the https.request() to blob.createWriteStream()? Is this the right approach?

I’ve spent a few days trying to find the right solution with different stream handlers but with precious little progress to show for it. Can someone help?

message: 'The rate of change requests to the object my-projectID/testimage.jpg exceeds the rate limit. Please reduce the rate of create, update, and delete requests.'
  const streamifier = require('streamifier');
  const {Storage} = require('@google-cloud/storage');
  const storage = new Storage({
      projectId: 'my-projectID',
      keyFile: '../config/my-projectID.json'
      });
  const bucket = storage.bucket('my-projectID');
  const blob = bucket.file('testimg.jpg');

app.post('/bam', passport.authenticate('basic', {session: false }), (req, res) => {
    
return new Promise((resolve, reject) => {
        https.request(req.body.pic, (response) => {            
            response.on('data', (d) => {
                streamifier.createReadStream(d)
                .pipe(blob.createWriteStream({
                    resumable:false, 
                    public:true,
                    metadata:{ contentType: 'image/jpeg' }
                    }));
            });
            
            response.on('finish', (done) => {
                console.log(done);
            });

            response.on('error', (err) => {
                console.log(err);
            });

        }).end();
    }); 

});

** Apologies for my ugly JS, I’m still at the bottom of ES6 learning curve.

Solution

I haven’t tried with https.request(), but I was able to upload an image directly to GCS without storing it locally by following the Cloud Storage Node.js Client:

const fs = require('fs')
const request = require('request')
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const myBucket = storage.bucket('my-bucket');
const blob = myBucket.file('image.jpg');
 
const uploadblob = (url, callback) => {
  request.head(url, (err, res, body) => {
    request(url)
      .pipe(blob.createWriteStream())
      .on('close', callback)
  })
}
const url = 'https://www.example/image.jpg'
 
uploadblob(url, () => {console.log('Done!')})

Answered By – alan

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published