2012-01-18 2 views
79

nodejs와 express를 사용하여 JSON을 사용하여 하나 이상의 객체 (배열)를 반환하고 싶습니다. 아래의 코드에서 한 번에 하나의 JSON 객체를 출력합니다. 그것은 작동하지만 이것은 내가 원하는 것만은 아닙니다. 많은 객체가 있기 때문에 생성 된 응답은 유효한 JSON 응답이 아닙니다.Node.js를 사용하여 복잡한 JSON 응답을 반환하는 방법은 무엇입니까?

나는 모든 객체를 배열에 추가하고 해당 배열을 res.end에 반환 할 수 있다는 것을 잘 알고 있습니다. 그러나 이것은 처리 및 메모리 집약적으로 무거워 질 수 있습니다.

nodej와 함께 이것을 달성하는 적절한 방법은 무엇입니까? 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

별도의 덩어리로 각 쿼리의 결과를 보낼 수 있습니다처럼 보이는 몽구스 문서를 검토 한 후 [편집]; 웹 서버는 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(); 
}); 
관련 문제