Usando nodejs y express, me gustaría devolver uno o varios objetos (matriz) usando JSON. En el siguiente código, saco un objeto JSON a la vez. Funciona, pero esto no es exactamente lo que quiero. La respuesta producida no es una respuesta JSON válida ya que tengo muchos objetos.
Soy consciente de que simplemente podría agregar todos los objetos a una matriz y devolver esa matriz específica en res.end. Sin embargo, me temo que esto podría volverse pesado de procesar y requerir mucha memoria.
¿Cuál es la forma correcta de lograr esto con nodejs? ¿Es query.each el método correcto para llamar?
app.get('/users/:email/messages/unread', function(req, res, next) {
var query = MessageInfo
.find({ $and: [ { 'email': req.params.email }, { 'hasBeenRead': false } ] });
res.writeHead(200, { 'Content-Type': 'application/json' });
query.each(function(err, msg) {
if (msg) {
res.write(JSON.stringify({ msgId: msg.fileName }));
} else {
res.end();
}
});
});
res.write(JSON.stringify(foo))
. Sifoo
es grande, es posible que deba cortarlo (en cadena, luego escribir trozos a la vez). Probablemente también quiera ver su encabezado"Content-Type":"application/json"
o similar según corresponda.No sé si esto es realmente diferente, pero en lugar de iterar sobre el cursor de consulta, podría hacer algo como esto:
query.exec(function (err, results){ if (err) res.writeHead(500, err.message) else if (!results.length) res.writeHead(404); else { res.writeHead(200, { 'Content-Type': 'application/json' }); res.write(JSON.stringify(results.map(function (msg){ return {msgId: msg.fileName}; }))); } res.end(); });
fuente
[Editar] Después de revisar la documentación de Mongoose, parece que puede enviar el resultado de cada consulta como un fragmento separado; el servidor web utiliza codificación de transferencia fragmentada de forma predeterminada lo que todo lo que tiene que hacer es envolver una matriz alrededor de los elementos para convertirlo en un objeto JSON válido.
Aproximadamente (no probado):
app.get('/users/:email/messages/unread', function(req, res, next) { var firstItem=true, query=MessageInfo.find(/*...*/); res.writeHead(200, {'Content-Type': 'application/json'}); query.each(function(docs) { // Start the JSON array or separate the next element. res.write(firstItem ? (firstItem=false,'[') : ','); res.write(JSON.stringify({ msgId: msg.fileName })); }); res.end(']'); // End the JSON array and response. });
Alternativamente, como mencionas, simplemente puedes enviar el contenido de la matriz tal cual. En este caso, el cuerpo de la respuesta se almacenará en búfer y se enviará inmediatamente, lo que puede consumir una gran cantidad de memoria adicional (por encima de lo que se requiere para almacenar los resultados en sí) para conjuntos de resultados grandes. Por ejemplo:
// ... var query = MessageInfo.find(/*...*/); res.writeHead(200, {'Content-Type': 'application/json'}); res.end(JSON.stringify(query.map(function(x){ return x.fileName })));
fuente