2012-01-18 12 views
79

nodejsとexpressを使用して、JSONを使用して1つまたは複数のオブジェクト(配列)を返したいと思います。以下のコードでは、一度に1つのJSONオブジェクトを出力します。それは動作しますが、これは私が欲しいものではありません。多くのオブジェクトがあるので、生成されるレスポンスは有効なJSONレスポンスではありません。Node.jsを使用して複雑なJSON応答を返す方法は?

私は、すべてのオブジェクトを配列に追加し、その特定の配列をres.endに返すことができたことをよく知っています。しかし、私はこのプロセスとメモリ集中的に重くなる恐れがあります。

nodejsでこれを達成する適切な方法は何ですか? query.eachは適切な呼び出し方法ですか?

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

答えて

181

急行3日のことができます。 res.json直接使用({FOO:バー})

res.json({ msgId: msg.fileName }) 

これは良いアイデアですdocumentation

+7

明示なしでそれを行う方法? – Piotrek

+0

@ Ludwik11 'res.write(JSON.stringify(foo))'です。 'foo'が大きければ、それを切り詰める(文字列化し、一度にチャンクを書く)必要があるかもしれません。おそらく、あなたのヘッダーの '' Content-Type ': "application/json"というようにしたいと思うかもしれません。 – OJFord

12

[編集]あなたが別のチャンクとして各クエリ結果を送信することができますようにマングースのマニュアルを確認した後、それが見えます。 Webサーバーはchunked transfer encodingby defaultを使用するので、有効なJSONオブジェクトにするには、項目の周りに配列をラップするだけです。

大雑把(未テスト):

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

、あなたが言及として-であるとして、あなたは単に配列の内容を送信することができます。この場合、the response body will be bufferedが直ちに送信され、大量の結果セットに対して大量の追加メモリ(結果自体を格納するのに必要な量を超える)を消費する可能性があります。たとえば:

// ... 
var query = MessageInfo.find(/*...*/); 
res.writeHead(200, {'Content-Type': 'application/json'}); 
res.end(JSON.stringify(query.map(function(x){ return x.fileName }))); 
+0

を参照してください。しかし、それは私に少しハッキーに見えます。私はnodejsがもう少しエレガントなものを提供することを望んでいました。 – Martin

18

これは本当に何が違うのであれば、私は知らないが、ではなく、クエリカーソルを反復、あなたはこのような何かを行うことができます:

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(); 
}); 
関連する問題