Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

523
Views
Use Cloud Function, descargue un archivo JSON de la URL y luego súbalo a un depósito de Cloud Storage, estado 200, pero el archivo JSON cargado tiene solo 20 bytes y está vacío.

Estoy tratando de usar la función de nube para descargar un archivo JSON desde aquí: http://jsonplaceholder.typicode.com/posts? luego cárguelo en el depósito de Cloud Storage.

El registro de ejecución de la función parece estar bien, el estado devuelve 200. Sin embargo, el archivo JSON cargado en el depósito tiene solo 20 bytes y está vacío (mientras que el archivo original tiene ~27 KB)


Entonces, ayúdenme si me perdí algo, hay código y registros:

índice.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}.`); };

paquete.json

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

Resultado:

ingrese la descripción de la imagen aquí

Tronco:

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

No escribo mucho NodeJS, pero creo que su problema es con el código asíncrono.

Usted crea la transmisión y luego emite el http.get pero no bloquea la devolución de llamada (canalización del archivo) antes de comenzar la carga de GCS.

Es posible que desee adjuntar un .on("finish", () => {...}) a la pipe y, en esa devolución de llamada, cargue el archivo en GCS.

NOTA IIRC GCS tiene un método que le permitirá escribir una secuencia directamente desde la memoria en lugar de pasar por un archivo.

NOTA : si coloca el objeto de storage en el espacio de nombres global, solo se creará cada vez que se cree la instancia y no cada vez que se invoque la función.

over 4 years ago · Santiago Trujillo Report

0

Como señaló @DazWilkin , hay problemas con el código asíncrono. Debe esperar a que onfinish() y luego continuar. Además, el método upload() también devuelve una promesa. Intente refactorizar su función en la sintaxis async-await como se muestra a continuación:

 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) }) }

Este ejemplo usa Axios pero puede hacer lo mismo con http .

Tenga en cuenta que puede cargar directamente el JSON obtenido como un archivo como este:

 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}.`); };

Puede leer más sobre el método save() en la documentación .

over 4 years ago · Santiago Trujillo Report

0

No necesita un flujo de escritura para obtener los datos de la URL, obtener la URL, esperar la respuesta para resolver, llamar al método response.toJson() apropiado.

Personalmente, prefiero usar Fetch y Axios en lugar de http , ya que son más limpios para trabajar. Pero con Nodes http puedes hacer lo siguiente:

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

Una vez que tenga eso, puede pasarlo directamente a un método de almacenamiento como un blob de datos o una matriz de bytes.

 byte[] byteArray = resultJson.toString().getBytes("UTF-8");
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!