Node.js로 복잡한 JSON 응답을 반환하는 방법은 무엇입니까?


82

nodejs와 express를 사용하여 JSON을 사용하여 하나 이상의 객체 (배열)를 반환하고 싶습니다. 아래 코드에서는 한 번에 하나의 JSON 객체를 출력합니다. 작동하지만 이것은 정확히 내가 원하는 것이 아닙니다. 생성 된 응답은 개체가 많기 때문에 유효한 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();
        }
    });
});

답변:


183

Express 3에서는 res.json ({foo : bar}) 직접 사용할 수 있습니다.

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

문서 보기


9
명시하지 않고 어떻게 할 수 있습니까?
Piotrek 2014

@ Ludwik11 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 문서를 검토 한 후 각 쿼리 결과를 별도의 청크로 보낼 수있는 것 같습니다. 웹 서버는 기본적으로 청크 전송 인코딩 을 사용 하므로 항목 주위에 배열을 감싸서 유효한 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 })));

이것은 좋은 생각입니다. 그러나 그것은 나에게 약간 해키 보인다. 나는 nodejs가 좀 더 우아한 것을 제공하기를 바랐습니다.
Martin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.