LoginSignup
0
0

More than 3 years have passed since last update.

Node.js/Expressのボディパーサーの仕様確認(エコーサーバー(echo-server))

Posted at

背景/目的

クライアント側からのリクエストを各種パーサーがどのようなオブジェクトや配列にしてくれるのを確認することを目的にリクエストの情報をまとめてレスポンスにそのまま返却するようなエコーサーバーを作ってみました。
その他、HTTPクライアントのリクエストが想定通りになっているかを確認するのにも使えると思うので記録として残しておきます。

仕様

リクエストの以下の情報をレスポンスJSONにまとめて返す。

  • ヘッダー情報
  • パス
  • HTTPメソッド(Verb)
  • クエリパラメータ
  • リクエストボディ(ある場合のみ)

準備

npmとかnode.jsはインストールされている前提。

mkdir echo-server
cd echo-server
npm init -f
npm install -y express
touch index.js

ソースコード

↑で作ったindex.js

index.js
'use strict';

const express = require('express');
const app = express();
const bodyParser = require('body-parser');

// Set body parser
app.use(bodyParser.urlencoded({ extended: true, type: 'application/x-www-form-urlencoded' }));
app.use(bodyParser.json({ type: 'application/json' }));
app.use(bodyParser.raw({ type: '*/*' }));

// All request process.
app.use((req, res, next) => {
  res.json({
    path: req.originalUrl.indexOf('?') === -1 ? req.originalUrl : req.originalUrl.substring(0, req.originalUrl.indexOf('?')),
    method: req.method,
    query: req.query,
    headers: req.headers,
    body: req.body ? (Object.keys(req.body).length ? req.body : undefined) : undefined
  });
});

// Create HTTP server.
const http = require('http');
const server = http.createServer(app);
const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000;
server.listen(port);
server.on('error', (err) => { console.error(err); });
server.on('listening', () => { console.log('listening on ' + port); });

実行

node index.js

実行結果確認

GETリクエスト

以下のようなクエリパラメータ名にすると配列にしてくれるみたいです。

request
$ curl -s -X GET -H "Authorization: Bearer dummmy" "http://localhost:3000/foo/bar?page=1&size=10&qarr[]=q1&qarr[]=q2&qarr[]=q3"  | jq .
response
{
  "path": "/foo/bar",
  "method": "GET",
  "query": {
    "page": "1",
    "size": "10",
    "qarr": [
      "q1",
      "q2",
      "q3"
    ]
  },
  "headers": {
    "host": "localhost:3000",
    "user-agent": "curl/7.68.0",
    "accept": "*/*",
    "authorization": "Bearer dummmy"
  }
}

POST(Json)

これはJSONなのでそのまま出る感じなのでさらっと。

request
$ curl -s -X POST -H "Authorization: Bearer dummmy" -H "Content-Type: application/json" -d '{"foo":"foo-value", "bar": "bar-value", "arr": [{"sub": "sub1"},{"sub": "
sub2"}]}' "http://localhost:3000/hogehoge"  | jq .
response
{
  "path": "/hogehoge",
  "method": "POST",
  "query": {},
  "headers": {
    "host": "localhost:3000",
    "user-agent": "curl/7.68.0",
    "accept": "*/*",
    "authorization": "Bearer dummmy",
    "content-type": "application/json",
    "content-length": "81"
  },
  "body": {
    "foo": "foo-value",
    "bar": "bar-value",
    "arr": [
      {
        "sub": "sub1"
      },
      {
        "sub": "sub2"
      }
    ]
  }
}

POST(フォーム)

Web画面(HTML)のフォーム送信(Content-Type: application/x-www-form-urlencoded)のケースです。
これは、 obj[sub]=obj-sub-value という名前の付け方をすると、以下のようなjsonにしてくれます。

"obj": {
    "sub": "sub-value"
}

ネストしたオブジェクトの場合は nested[sub1][sub2]=sub1-sub2 という名前の付け方をすると

"nested": {
  "sub1": {
    "sub2": "sub1-sub2"
  }
}

つまり、各フォーム要素のname属性を意識してつければ、例えばBackendのデータベースがMongoDBのようなオブジェクト形式だった場合にサーバー側でFormをオブジェクトの形に整形(組み立てる)処理を書かなくても済むわけです。もちろんJSonスキーマだったり、バリデーションのチェックは必要ですが。。

request
$ curl -s -X POST -H "Authorization: Bearer dummmy" -H "Content-Type: application/x-www-form-urlencoded" -d 'foo=foo-valoue&bar=bar-value&arr=arr1&arr=arr2&arr=arr3&
obj[sub]=sub-value&nested[sub1][sub2]=sub1-sub2' "http://localhost:3000/foo/bar" | jq .
response
{
  "path": "/foo/bar",
  "method": "POST",
  "query": {},
  "headers": {
    "host": "localhost:3000",
    "user-agent": "curl/7.68.0",
    "accept": "*/*",
    "authorization": "Bearer dummmy",
    "content-type": "application/x-www-form-urlencoded",
    "content-length": "103"
  },
  "body": {
    "foo": "foo-valoue",
    "bar": "bar-value",
    "arr": [
      "arr1",
      "arr2",
      "arr3"
    ],
    "obj": {
      "sub": "sub-value"
    },
    "nested": {
      "sub1": {
        "sub2": "sub1-sub2"
      }
    }
  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0