ノードまたはExpressを使用してJSONを返す適切な方法


438

したがって、次のJSONオブジェクトをフェッチすることができます。

$ curl -i -X GET http://echo.jsontest.com/key/value/anotherKey/anotherValue
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=ISO-8859-1
Date: Wed, 30 Oct 2013 22:19:10 GMT
Server: Google Frontend
Cache-Control: private
Alternate-Protocol: 80:quic,80:quic
Transfer-Encoding: chunked

{
   "anotherKey": "anotherValue",
   "key": "value"
}
$

nodeまたはexpressを使用してサーバーからの応答でまったく同じ本文を生成する方法はありますか?明らかに、ヘッダーを設定して、応答のcontent-typeが「application / json」になることを示すことができますが、オブジェクトの書き込み/送信にはさまざまな方法があります。私が一般的に使用されているのを見たのは、次の形式のコマンドを使用することです。

response.write(JSON.stringify(anObject));

ただし、これには「問題」であるかのように議論できる2つのポイントがあります。

  • 文字列を送信しています。
  • また、最後に改行文字はありません。

別のアイデアは、コマンドを使用することです:

response.send(anObject);

これは、上の最初の例と同様に、curlの出力に基づいてJSONオブジェクトを送信しているようです。ただし、端末でcurlが再び使用されている場合、本文の最後に改行文字はありません。では、実際に、nodeまたはnode / expressを使用して最後に改行文字を追加して、このようなものを書き留めることはできますか?

回答:


618

その応答も文字列です。もしあなたがプレティファイされた応答を送信したい場合、いくつかの厄介な理由のために、 JSON.stringify(anObject, null, 3)

Content-Typeヘッダーもに設定することが重要ですapplication/json

var http = require('http');

var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ a: 1 }));
});
app.listen(3000);

// > {"a":1}

プリティファイド:

var http = require('http');

var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ a: 1 }, null, 3));
});
app.listen(3000);

// >  {
// >     "a": 1
// >  }

なぜ改行で終了したいのか正確にはわかりませんが、それJSON.stringify(...) + '\n'を達成するために行うことができます。

急行

エクスプレスでは、代わりにオプションを変更することでこれを行うことができます

'json replacer' JSON代替コールバック、デフォルトではnull

'json spaces' フォーマット用のJSON応答スペース、デフォルトでは開発では2、本番では0

実際には40に設定することはお勧めしません

app.set('json spaces', 40);

次に、jsonで応答します。

res.json({ a: 1 });

'json spaces'構成を使用してそれをかっこよくします。


3
お時間をいただきありがとうございます。正直なところ、私は問題ありません。それはちょうど、(異なるタイムゾーンの)誰かがgetを実行したかったために使用していた形式について不平を言っただけで、何らかの理由で私のオブジェクトを正しく読み取ることができませんでした。stringifyの素晴らしいバージョンに注目していただきありがとうございます。:)
MightyMouse 2013年

2
この人は、JSON文字列をオブジェクトに解析するか、ブラウザ拡張機能を使用して、手動で読み取るのではなく、
bevacqua 2013年

2
@akshayさらに良いres.sendことにcontent-type、送信されたアイテムがオブジェクトまたは配列の場合、自動的にをJSONに設定します。
royhowie

3
私はあなたが使用するためのものだと思うres.end()あなたにhttp(非明示)の例
トビアスフンケ

2
@TobiasFünkeは正しいと思います。res.send()動かない。間違いの場合は修正してください。res.end()正常に動作しています。ありがとうございます。
Kaushal28 2017年

409

Express.js 3x以降、応答オブジェクトにはjson()メソッドがあり、すべてのヘッダーが正しく設定され、JSON形式で応答が返されます。

例:

res.json({"foo": "bar"});

お時間をいただきありがとうございます。しかし、私の質問は当時のヘッダーに関するものではありませんでした。カールを通して言うことができる結果についての詳細でした。とにかくありがとう。
MightyMouse

53
わかりましたが、このメソッドも適切にフォーマットされたJSONを返します。これは応答の一部です。したがって、res.json()は正しいヘッダーを設定し、JSON.stringify()が自動的に応答します。
JamieL

19

あなたがjsonファイルを送信しようとしている場合は、ストリームを使用できます

var usersFilePath = path.join(__dirname, 'users.min.json');

apiRouter.get('/users', function(req, res){
    var readable = fs.createReadStream(usersFilePath);
    readable.pipe(res);
});

10
fsとは何ですか、パイプとは何ですか、何が読み取り可能ですか?あなたの答えはもっと謎です
Aakash Dave '30


6

Expressを使用している場合、uはこれを使用できます。

res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({key:"value"}));

またはこれだけ

res.json({key:"value"});

5

パイプと多くのプロセッサの1つを使用して、それを美化することができます。アプリは常に可能な限り小さな負荷で応答する必要があります。

$ curl -i -X GET http://echo.jsontest.com/key/value/anotherKey/anotherValue | underscore print

https://github.com/ddopson/underscore-cli


4

そのためのヘルパーを作成できます。ヘルパー関数を作成して、アプリケーション内のあらゆる場所で使用できるようにします。

function getStandardResponse(status,message,data){
    return {
        status: status,
        message : message,
        data : data
     }
}

これが私がすべてのトピックを取得しようとしている私のトピックルートです

router.get('/', async (req, res) => {
    const topics = await Topic.find().sort('name');
    return res.json(getStandardResponse(true, "", topics));
});

私たちが得る応答

{
"status": true,
"message": "",
"data": [
    {
        "description": "sqswqswqs",
        "timestamp": "2019-11-29T12:46:21.633Z",
        "_id": "5de1131d8f7be5395080f7b9",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575031579309.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "sqswqswqs",
        "timestamp": "2019-11-29T12:50:35.627Z",
        "_id": "5de1141bc902041b58377218",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575031835605.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": " ",
        "timestamp": "2019-11-30T06:51:18.936Z",
        "_id": "5de211665c3f2c26c00fe64f",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575096678917.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "null",
        "timestamp": "2019-11-30T06:51:41.060Z",
        "_id": "5de2117d5c3f2c26c00fe650",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575096701051.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "swqdwqd wwwwdwq",
        "timestamp": "2019-11-30T07:05:22.398Z",
        "_id": "5de214b2964be62d78358f87",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575097522372.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    },
    {
        "description": "swqdwqd wwwwdwq",
        "timestamp": "2019-11-30T07:36:48.894Z",
        "_id": "5de21c1006f2b81790276f6a",
        "name": "topics test xqxq",
        "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575099408870.jpg",
        "category_id": "5de0fe0b4f76c22ebce2b70a",
        "__v": 0
    }
      ]
}

3

ミドルウェアを使用してデフォルトのContent-Typeを設定し、特定のAPIに対してContent-Typeを異なる方法で設定できます。次に例を示します。

const express = require('express');
const app = express();

const port = process.env.PORT || 3000;

const server = app.listen(port);

server.timeout = 1000 * 60 * 10; // 10 minutes

// Use middleware to set the default Content-Type
app.use(function (req, res, next) {
    res.header('Content-Type', 'application/json');
    next();
});

app.get('/api/endpoint1', (req, res) => {
    res.send(JSON.stringify({value: 1}));
})

app.get('/api/endpoint2', (req, res) => {
    // Set Content-Type differently for this particular API
    res.set({'Content-Type': 'application/xml'});
    res.send(`<note>
        <to>Tove</to>
        <from>Jani</from>
        <heading>Reminder</heading>
        <body>Don't forget me this weekend!</body>
        </note>`);
})

2

質問のヘッダーの半分について、私はres.typeここに叫び声をあげるつもりです:

res.type('json')

に相当

res.setHeader('Content-Type', 'application/json')

ソース:エクスプレスドキュメント

Content-Type HTTPヘッダーを、指定されたタイプのmime.lookup()によって決定されたMIMEタイプに設定します。typeに「/」文字が含まれている場合、Content-Typeをtypeに設定します。


1

古いバージョンのExpressはbodyParserミドルウェアを使用するapp.use(express.json())bodyParser.json() 、詳細を読みます

Expressの最新バージョンでは、簡単に使用できます res.json()

const express = require('express'),
    port = process.env.port || 3000,
    app = express()

app.get('/', (req, res) => res.json({key: "value"}))

app.listen(port, () => console.log(`Server start at ${port}`))

親愛なる、あなたは要求と応答を混同しています。BodyParserミドルウェアは、リクエストを解析するためのものreq.bodyで、リクエストのボディとして送信されるオブジェクトです。
Matthias Hryniszak
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.