Node.js के साथ एक जटिल JSON प्रतिक्रिया कैसे लौटाएं?


82

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

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

नोडज के साथ इसे हासिल करने का उचित तरीका क्या है? क्या 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();
        }
    });
});

जवाबों:


183

एक्सप्रेस 3 पर आप सीधे res.json ({foo: bar}) का उपयोग कर सकते हैं

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

प्रलेखन देखें


9
एक्सप्रेस के बिना ऐसा कैसे करें?
पियोट्रेक

@ लुडविक 11 res.write(JSON.stringify(foo))। यदि fooआपको इसे बड़ा करने की आवश्यकता हो सकती है (कठोर करें, तो एक बार में चंक लिखें)। संभवतः अपने हेडर "Content-Type":"application/json"या समान को भी उपयुक्त बनाना चाहते हैं।
OJFord

21

मुझे नहीं पता कि यह वास्तव में कोई भिन्न है, लेकिन क्वेरी कर्सर पर पुनरावृति के बजाय, आप ऐसा कुछ कर सकते हैं:

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

12

[संपादित करें] Mongoose प्रलेखन की समीक्षा करने के बाद, ऐसा लगता है कि आप प्रत्येक क्वेरी परिणाम को एक अलग चंक के रूप में भेज सकते हैं; वेब सर्वर डिफ़ॉल्ट रूप से chunked ट्रांसफर एन्कोडिंग का उपयोग करता है, इसलिए आपको बस इतना करना है कि इसे एक वैध 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.
});

वैकल्पिक रूप से, जैसा कि आप उल्लेख करते हैं, आप बस सरणी सामग्री को इस रूप में भेज सकते हैं। इस मामले में प्रतिक्रिया शरीर को बफ़र किया जाएगा और तुरंत भेजा जाएगा , जो बड़ी मात्रा में अतिरिक्त मेमोरी का उपभोग कर सकता है (बड़े परिणाम सेट के लिए खुद को स्टोर करने के लिए जो आवश्यक है)। उदाहरण के लिए:

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

यह एक अच्छा विचार है। हालांकि यह मेरे लिए थोड़ा हैकिंग लगता है। मैं नोड्ज के लिए उम्मीद कर रहा था कि वह कुछ और अधिक सुरुचिपूर्ण प्रदान करेगा।
मार्टिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.