2012-01-18 13 views
79

नोडजेस और एक्सप्रेस का उपयोग करके, मैं JSON का उपयोग कर एक या एकाधिक ऑब्जेक्ट (सरणी) वापस करना चाहता हूं। नीचे दिए गए कोड में मैं एक समय में एक JSON ऑब्जेक्ट आउटपुट करता हूं। यह काम करता है लेकिन यह वही नहीं है जो मैं चाहता हूं। उत्पादित प्रतिक्रिया वैध JSON प्रतिक्रिया नहीं है क्योंकि मेरे पास कई ऑब्जेक्ट्स हैं।Node.js के साथ एक जटिल JSON प्रतिक्रिया कैसे वापस करें?

मुझे अच्छी तरह पता है कि मैं बस सभी ऑब्जेक्ट्स को सरणी में जोड़ सकता हूं और res.end में उस विशिष्ट सरणी को वापस कर सकता हूं। हालांकि मुझे डर है कि यह प्रक्रिया और गहन स्मृति के लिए भारी हो सकता है।

नोडजेस के साथ इसे स्वीकार करने का उचित तरीका क्या है? पूछताछ है। कॉल करने के लिए सही तरीका है?

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

@ लुडविक 11 'res.write (JSON.stringify (foo)) '। यदि 'foo' बड़ा है तो आपको इसे काटने की आवश्यकता हो सकती है (स्ट्रिंग करें, फिर एक समय में खंड लिखें)। शायद आपके हेडर को "सामग्री-प्रकार": "एप्लिकेशन/जेसन" या उपयुक्त के रूप में भी देखना चाहते हैं। – OJFord

12

[संपादित करें] नेवला दस्तावेज़ों की समीक्षा, ऐसा लगता है कि आप एक अलग हिस्सा के रूप में प्रत्येक क्वेरी परिणाम भेज सकते हैं के बाद; वेब सर्वर chunked transfer encodingby default का उपयोग करता है, इसलिए आपको केवल एक वैध JSON ऑब्जेक्ट बनाने के लिए आइटम्स के चारों ओर एक सरणी लपेटनी है।

मोटे तौर पर (untested):

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

देखें यह एक अच्छा विचार है। हालांकि यह मेरे लिए थोड़ा हैकी दिखता है। मैं नोडज के लिए कुछ और अधिक सुरुचिपूर्ण प्रदान करने की उम्मीद कर रहा था। – 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(); 
}); 
संबंधित मुद्दे