Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

526
Visualizações
Use Cloud Function download a JSON file from URL then upload to a Cloud Storage bucket, status 200 but JSON file uploaded is only 20 bytes and empty

I'm trying to use the cloud function to download a JSON file from here: http://jsonplaceholder.typicode.com/posts? then upload it to Cloud Storage bucket.

Log of function execution seems fine, the status returns 200. However, the JSON file uploaded to the bucket is only 20 Bytes and it is empty (while the original file is ~27 KB)


So please help me if I missed something, there is code and logs:

index.js

const {Storage} = require('@google-cloud/storage');
    
exports.writeToBucket = (req, res) => {
    const http = require('http');
    const fs = require('fs');
    
    const file = fs.createWriteStream("/tmp/post.json");
    const request = http.get("http://jsonplaceholder.typicode.com/posts?", function(response) {
      response.pipe(file);
    });
    
    
    console.log('file downloaded');
    
    // Imports the Google Cloud client library
    const {Storage} = require('@google-cloud/storage');
    
    // Creates a client
    const storage = new Storage();
    const bucketName = 'tft-test-48c87.appspot.com';
    const filename = '/tmp/post.json';

    // Uploads a local file to the bucket
    storage.bucket(bucketName).upload(filename, {
      gzip: true,
      metadata: {
        cacheControl: 'no-cache',
      },
    });

    res.status(200).send(`${filename} uploaded to ${bucketName}.`);
    
};

package.json

{
  "name": "sample-http",
  "version": "0.0.1",
  "dependencies": {
        "@google-cloud/storage": "^3.0.3"
    }
}

Result:

enter image description here

Log:

enter image description here

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

I don't write much NodeJS but I think your issue is with async code.

You create the stream and then issue the http.get but you don't block on the callback (piping the file) completing before you start the GCS upload.

You may want to attach an .on("finish", () => {...}) to the pipe and in that callback, upload the file to GCS.

NOTE IIRC GCS has a method that will let you write a stream directly from memory rather than going through a file.

NOTE if you pull the storage object up into the global namespace, it will only be created whenever the instance is created and not every time the function is invoked.

over 4 years ago · Santiago Trujillo Relatório

0

As pointed by @DazWilkin, there are issues with asynchronous code. You must wait for onfinish() to trigger and then proceed. Also the upload() method returns a promise too. Try refactoring your function in async-await syntax as shown below:

exports.writeToBucket = async (req, res) => {
  const http = require('http');
  const fs = require('fs');

  // Imports the Google Cloud client library
  const {Storage} = require('@google-cloud/storage');
    
  // Creates a client
  const storage = new Storage();
  const bucketName = 'tft-test-48c87.appspot.com';
  const filename = '/tmp/post.json';  

  await downloadJson()

  // Uploads a local file to the bucket
  await storage.bucket(bucketName).upload(filename, {
    gzip: true,
    metadata: {
      cacheControl: 'no-cache',
    },
  });

  res.status(200).send(`${filename} uploaded to ${bucketName}.`);
}

const downloadJson = async () => {
 const Axios = require('axios')
 const fs = require("fs")
 const writer = fs.createWriteStream("/tmp/post.json")
 const response = await Axios({
   url: "http://jsonplaceholder.typicode.com/posts",
   method: 'GET',
   responseType: 'stream'
 })
 response.data.pipe(writer)
 return new Promise((resolve, reject) => {
   writer.on('finish', resolve)
   writer.on('error', reject)
 })
}

This example uses Axios but you can do the same with http.

Do note that you can directly upload the fetched JSON as a file like this:

exports.writeToBucket = async (req, res) => {
  const Axios = require("axios");
  const { Storage } = require("@google-cloud/storage");

  const storage = new Storage();
  const bucketName = "tft-test-48c87.appspot.com";
  const filename = "/tmp/post.json";

  const { data } = await Axios.get("http://jsonplaceholder.typicode.com/posts");

  const file = storage.bucket(bucketName).file("file.json");
  const contents = JSON.stringify(data);
  await file.save(contents);

  res.status(200).send(`${filename} uploaded to ${bucketName}.`);
};

You can read more about the save() method in the documentation.

over 4 years ago · Santiago Trujillo Relatório

0

You don't need a write stream to get the URL data, fetch the URL, await the response to resolve, call the appropriate response.toJson() method.

Personally, I prefer to use Fetch and Axios over http as they are cleaner to work with. But with Nodes http you can do the following:


https.get(url,(res) => {
    let body = "";

    res.on("data", (chunk) => {
        body += chunk;
    });

    res.on("end", () => {
        try {
            let json = JSON.parse(body);
            // do something with JSON
        } catch (error) {
            console.error(error.message);
        };
    });

}).on("error", (error) => {
    console.error(error.message);
});

Once you have that, you can pass it directly to a storage method as a data blob or byte array.

byte[] byteArray = resultJson.toString().getBytes("UTF-8");
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda