2012-01-18 35 views
79

使用nodejs和express,我想使用JSON返回一個或多個對象(數組)。在下面的代碼中,我一次輸出一個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 2014-04-28 18:11:31

+0

@ Ludwik11'res.write(JSON.stringify(foo))'。如果'foo'很大,你可能需要將它切分(串化,然後一次寫入塊)。可能還需要選擇你的頭文件「Content-Type」:「application/json」或類似的。 – OJFord 2015-08-12 09:30:42

12

[編輯]審查貓鼬文檔,它看起來像你可以給每個查詢結果作爲一個單獨的塊之後;網絡服務器使用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 2012-01-18 13:59:32

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