2012-01-18 35 views
79

Sử dụng các nút và biểu thức, tôi muốn trả lại một hoặc nhiều đối tượng (mảng) bằng cách sử dụng JSON. Trong đoạn mã dưới đây, tôi xuất một đối tượng JSON tại một thời điểm. Nó hoạt động nhưng đây không phải là những gì tôi muốn. Phản hồi được tạo ra không phải là một phản ứng JSON hợp lệ vì tôi có nhiều đối tượng.Làm thế nào để trả về một phản ứng JSON phức tạp với Node.js?

Tôi biết rõ rằng tôi có thể chỉ cần thêm tất cả các đối tượng vào một mảng và trả về mảng cụ thể đó trong res.end. Tuy nhiên tôi sợ điều này có thể trở nên nặng nề để xử lý và bộ nhớ chuyên sâu.

Cách thích hợp để đạt được điều này với nodej là gì? Là query.each phương pháp đúng để gọi?

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

Trả lời

181

Mở nhanh 3 bạn có thể sử dụng trực tiếp res.json ({foo: thanh})

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

Xem documentation

+7

làm thế nào để làm điều đó mà không thể hiện? – Piotrek

+0

@ Ludwik11 'res.write (JSON.stringify (foo))'. Nếu 'foo' lớn, bạn có thể cần phải cắt nó lên (xâu chuỗi, sau đó viết đoạn văn tại một thời điểm). Có lẽ cũng muốn lấy tiêu đề của bạn '" Content-Type ":" application/json "' hoặc tương tự như thích hợp. – OJFord

12

[Chỉnh sửa] Sau khi xem xét các tài liệu Mongoose, có vẻ như bạn có thể gửi mỗi kết quả truy vấn như một đoạn riêng biệt; máy chủ web sử dụng chunked transfer encodingby default vì vậy tất cả những gì bạn phải làm là bao bọc một mảng quanh các mục để biến nó trở thành đối tượng JSON hợp lệ.

Khoảng (chưa được kiểm tra):

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

Ngoài ra, như bạn đề cập, bạn chỉ có thể gửi nội dung mảng như nó vốn có. Trong trường hợp này, the response body will be buffered và được gửi ngay lập tức, có thể tiêu tốn một lượng lớn bộ nhớ bổ sung (trên những gì cần thiết để lưu trữ kết quả) cho các tập kết quả lớn. Ví dụ:

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

Đây là một ý tưởng tốt. Tuy nhiên có vẻ hơi khó khăn với tôi. Tôi đã hy vọng cho nodejs để cung cấp một cái gì đó một chút thanh lịch hơn. – Martin

18

Tôi không biết nếu điều này thực sự là bất kỳ khác nhau, nhưng thay vì lặp qua các con trỏ truy vấn, bạn có thể làm một cái gì đó như thế này:

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(); 
}); 
Các vấn đề liên quan