RESTで応答するテストサーバーをノンコーディングで作る

ちょっと必要だったので、nodeでやってみた。
テストデーターの生成にはコーディングが必要だけど、数行のたいしたことない程度。

  • 使えたところ
    • サーバー側はノンコーディングで一瞬で立つ
    • テキストを使うのでダミーデータはすぐ作れる
  • 使いにくかったところ
    • keyがidに指定した連番になる
    • 検索は時間かかる
    • 追記すると2秒くらいはかかる

さくらのクラウドUbuntuインスタンスを生成

sshでアクセス。サボってrootで作業。
nodeとnpmをインストール。

# apt-get update
# apt-get install nodejs npm
# nodejs -v
v4.2.6
# npm -v
3.5.2

サボって、作業ディレクトリも作らず/rootのまま。
json-serverのインストール。

# npm i json-server -g

fakerで30万件のダミーデータの作成

# npm install faker
# vi make_fakedata.js

var counter = 10;
var faker = require('faker');
var db = { devices: [] };
for (var i=1; i<=counter; i++) {
  db. devices.push({
    uuid: faker.random.uuid(),
    mac: faker.internet.mac(),
    ipv4: faker.internet.ip(),
    id: i
  });
}
console.log(JSON.stringify(db));

テスト。

# nodejs make_fakedata.js
{"devices":[{"uuid":"c1305913-b21f-4714-b66b-79fffc625a32","mac":"c1:d5:32:12:0a:af","ipv4":"55.120.235.205","id":1},{"uuid":"f3d898cc-0c0f-45e1-b072-4021128db61f","mac":"48:38:76:28:fb:24","ipv4":"179.135.210.85","id":2},{"uuid":"2278dadd-2f80-4947-b2bc-1cf31b84d72c","mac":"c7:48:5c:68:d2:84","ipv4":"16.165.28.98","id":3},{"uuid":"81c5818f-22b2-4e5c-9c07-ca63acc19009","mac":"07:27:a7:20:31:45","ipv4":"189.132.206.77","id":4},{"uuid":"36c5cbd3-6da6-45be-9f6f-8eb1958d93e8","mac":"0c:ce:6b:80:64:66","ipv4":"146.204.232.92","id":5},{"uuid":"e3c1ad07-af87-4e3c-8934-888e62b15c0e","mac":"0c:36:dc:52:f2:66","ipv4":"60.174.66.106","id":6},{"uuid":"fe72849e-74d7-4177-9802-349838799333","mac":"80:36:b5:fb:b9:42","ipv4":"13.41.45.14","id":7},{"uuid":"5fc210bd-1538-4bd1-8d6d-94447f07fd7e","mac":"27:e0:b6:01:63:13","ipv4":"40.101.51.226","id":8},{"uuid":"fa362123-f7bf-47c2-bcc7-9be018436a05","mac":"4e:ef:ea:06:3c:15","ipv4":"52.83.186.234","id":9},{"uuid":"7674474d-4114-4f27-a3c2-caaf1756f96b","mac":"74:06:ab:7d:0f:9d","ipv4":"141.83.211.251","id":10}]}

30万件に増やして作成。

# vi make_fakedata.js

var counter = 300000;

吐く。

# time nodejs make_fakedata.js > db.json

real 0m21.968s
user 0m21.712s
sys 0m0.220s

サイズ感。

# ls -lh db.json
-rw-r--r-- 1 root root 32M Apr 20 22:58 db.json

起動テスト

# json-server --watch db.json
/usr/bin/env: ‘node’: No such file or directory

Ubuntuはこういうのがめんどくさいね。

# which nodejs
/usr/bin/nodejs
# ln -s /usr/bin/nodejs /usr/bin/node

再度。

# json-server --watch db.json

\{^_^}/ hi!

Loading db.json
Done

Resources
http://localhost:3000/devices

Home
http://localhost:3000

Type s + enter at any time to create a snapshot of the database
Watching...

ブラウザでport3000にアクセスする。
なにやら画面が出てきた。動いているようだ。

動作テスト

ローカルから。

# time curl -X GET "http://XXX.XXX.XXX.XXX:3000/devices/1"
{
"uuid": "9ff31ac6-1b68-488e-abd3-1be571cae96b",
"mac": "61:1e:c2:6b:f2:dc",
"ipv4": "230.130.203.248",
"id": 1
}
real 0m0.012s
user 0m0.004s
sys 0m0.000s

リモートなコンソールから。

$ time curl -X GET "http://XXX.XXX.XXX.XXX:3000/devices/1"
{
"uuid": "9ff31ac6-1b68-488e-abd3-1be571cae96b",
"mac": "61:1e:c2:6b:f2:dc",
"ipv4": "230.130.203.248",
"id": 1
}
real 0m0.102s
user 0m0.030s
sys 0m0.000s

結構速いな。
お尻で変わる?

$ time curl -X GET "http://XXX.XXX.XXX.XXX:3000/devices/300000"
{
"uuid": "d42f3058-18af-42a3-b386-c40346663b03",
"mac": "64:6b:2c:3e:c8:1b",
"ipv4": "35.141.241.191",
"id": 300000
}
real 0m0.295s
user 0m0.020s
sys 0m0.010s

ちょっと遅くなるか?

ページ表示

# time curl -X GET "http://XXX.XXX.XXX.XXX:3000/devices/?_page=300"
[
{
"uuid": "5181a658-e09c-4240-bad1-eae1994afa50",
"mac": "cf:c6:83:91:83:03",
"ipv4": "201.52.9.202",
"id": 2991
},
{
"uuid": "caa13979-913f-4293-9af2-2690f5f62ad8",
"mac": "c9:0a:ce:1f:71:ea",
"ipv4": "134.201.251.112",
"id": 2992
},
{
"uuid": "aef66395-48b6-4c70-a36f-00cd71ada02a",
"mac": "e0:4f:ce:97:dd:3a",
"ipv4": "252.0.154.170",
"id": 2993
},
{
"uuid": "8a43dbd5-1aad-417d-9304-02a2171cf510",
"mac": "b8:4e:af:cc:04:3f",
"ipv4": "250.255.158.145",
"id": 2994
},
{
"uuid": "ab2a1789-117a-4147-8070-e6de311f1b8b",
"mac": "fd:76:79:09:aa:1d",
"ipv4": "213.199.191.146",
"id": 2995
},
{
"uuid": "b88a7a6c-d004-4d36-81ff-e173fe0ed1ea",
"mac": "f4:59:61:0b:23:be",
"ipv4": "136.238.119.171",
"id": 2996
},
{
"uuid": "bd34cbd1-64eb-46ca-882c-8066d28485c9",
"mac": "28:79:e1:34:1f:52",
"ipv4": "244.206.222.224",
"id": 2997
},
{
"uuid": "cf1f5712-40e7-41ad-b0e8-3131ae42d514",
"mac": "b7:8e:03:18:f7:cd",
"ipv4": "220.246.58.101",
"id": 2998
},
{
"uuid": "50960509-0cfa-4f6d-bbe3-a78173b22f38",
"mac": "99:ed:ef:a8:89:89",
"ipv4": "124.46.195.80",
"id": 2999
},
{
"uuid": "5a36c403-bf97-4c9d-94d0-b573a175ea04",
"mac": "9c:a1:6a:20:0b:12",
"ipv4": "32.64.176.38",
"id": 3000
}
]
real 0m0.486s
user 0m0.004s
sys 0m0.000s

10件表示された。このページ表示件数パラメータがいじれるといいのに。
おっと、_limit設定あった。

# curl -X GET "http://localhost:3000/devices/?_page=3&_limit=3"
[
{
"uuid": "dd651687-fbde-46fa-8b25-0f4ce3ca0820",
"mac": "05:66:a1:bf:c2:5b",
"ipv4": "95.45.132.54",
"id": 7
},
{
"uuid": "25aa9b73-3817-435c-8a3a-66b471f62c0f",
"mac": "ec:5a:71:59:75:71",
"ipv4": "92.209.6.102",
"id": 8
},
{
"uuid": "83563893-e0e7-4b6b-8205-29ad4a01270e",
"mac": "55:bd:31:4a:6e:b0",
"ipv4": "214.142.77.147",
"id": 9
}
]

レコード追加のテスト

重複idで書き込んでみる。

# curl -X POST -H "Content-Type: application/json" -d '{
> "uuid": "5181a658-e09c-4240-bad1-eae1994afa51",
> "mac": "cf:c6:83:91:83:04",
> "ipv4": "201.52.9.203",
> "id": 30001
> }' "http://XXX.XXX.XXX.XXX:3000/devices"
Error: Insert failed; duplicate id.
at Function.module.exports.insert (/usr/local/lib/node_modules/json-server/node_modules/lodash-id/src/index.js:49:18)
at /usr/local/lib/node_modules/json-server/node_modules/lodash/lodash.js:4379:28
at arrayReduce (/usr/local/lib/node_modules/json-server/node_modules/lodash/lodash.js:704:21)
at baseWrapperValue (/usr/local/lib/node_modules/json-server/node_modules/lodash/lodash.js:4378:14)
at LodashWrapper.wrapperValue (/usr/local/lib/node_modules/json-server/node_modules/lodash/lodash.js:9067:14)
at create (/usr/local/lib/node_modules/json-server/lib/server/router/plural.js:226:50)
at Layer.handle [as handle_request] (/usr/local/lib/node_modules/json-server/node_modules/express/lib/router/layer.js:95:5)
at next (/usr/local/lib/node_modules/json-server/node_modules/express/lib/router/route.js:137:13)
at next (/usr/local/lib/node_modules/json-server/node_modules/express/lib/router/route.js:131:14)
at Route.dispatch (/usr/local/lib/node_modules/json-server/node_modules/express/lib/router/route.js:112:3)

上書きされるわけではない。
サーバーは落ちたりしていない。


未登録idで書いてみる。

# time curl -X POST -H "Content-Type: application/json" -d '{
> "uuid": "5181a658-e09c-4240-bad1-eae1994afa52",
> "mac": "cf:c6:83:91:83:05",
> "ipv4": "201.52.9.204",
> "id": 300001
> }' "http://153.127.217.118:3000/devices"
{
"uuid": "5181a658-e09c-4240-bad1-eae1994afa52",
"mac": "cf:c6:83:91:83:05",
"ipv4": "201.52.9.204",
"id": 300001
}
real 0m2.373s
user 0m0.004s
sys 0m0.000s

2.3秒はかかりすぎか…

# tail -n 8 db.json
{
"uuid": "5181a658-e09c-4240-bad1-eae1994afa52",
"mac": "cf:c6:83:91:83:05",
"ipv4": "201.52.9.204",
"id": 300001
}
]
}

追記されている。

検索

フィルターを使った絞込み。

# curl -X GET "http://localhost:3000/devices?mac=cf:c6:83:91:83:05"
[
{
"uuid": "5181a658-e09c-4240-bad1-eae1994afa52",
"mac": "cf:c6:83:91:83:05",
"ipv4": "201.52.9.204",
"id": 300002
}
]

コンソールログはこんなのが出ている。

GET /devices?mac=cf:c6:83:91:83:05 200 1478.592 ms - 140

少し時間かかってるかな。
&でつないで、複数のフィルタを設定することもできる。


論理演算子でフィルタしてみる。
_gteを付けると>。
_lteを付けると<。
_neを付けると、その値を除外。

# curl -X GET "http://localhost:3000/devices?id_gte=300000&id_lte=300001"
[
{
"uuid": "d42f3058-18af-42a3-b386-c40346663b03",
"mac": "64:6b:2c:3e:c8:1b",
"ipv4": "35.141.241.191",
"id": 300000
},
{
"uuid": "5181a658-e09c-4240-bad1-eae1994afa51",
"mac": "cf:c6:83:91:83:04",
"ipv4": "201.52.9.203",
"id": 300001
}
]


こういうフィルタも書けるハズだけど、うまくいかなかった。

# curl -X GET "http://localhost:3000/devices?ipv4.201"

ソート

_sortと_orderプロパティが設定できる。

# curl -X GET "http://localhost:3000/devices?id_gte=3000&id_lte=30005&_sort=uuid&_order=DESC"
[
{
"uuid": "f55835e4-f32a-4235-897d-276727ce7233",
"mac": "be:64:5b:44:66:20",
"ipv4": "255.250.236.181",
"id": 30000
},
{
"uuid": "da22ad88-34fb-4d3c-9404-241039d086e3",
"mac": "29:7c:53:f7:f6:b3",
"ipv4": "174.162.24.144",
"id": 30003
},
{
"uuid": "87b7a857-66c4-484a-8d60-e731e071cc9a",
"mac": "a3:a4:4c:0e:da:f4",
"ipv4": "114.181.18.50",
"id": 30005
},
{
"uuid": "69b13648-a028-4ad8-9a3b-0fc332a15262",
"mac": "d8:df:21:de:36:24",
"ipv4": "205.72.27.216",
"id": 30002
},
{
"uuid": "6170f3e5-e5e5-4dfd-923b-916dcd1d8be3",
"mac": "e4:b0:53:13:37:d3",
"ipv4": "253.22.9.206",
"id": 30004
},
{
"uuid": "25a344a0-6c85-48cd-a153-d912d3c7614a",
"mac": "a5:ba:23:f6:25:48",
"ipv4": "210.133.43.253",
"id": 30001
}
]

レコードの更新

PATCHできるかな?

# curl -X PATCH -H "Content-Type: application/json" -d '{
> "ipv4": "192.168.0.1",
> "id": 30001
> }' "http://localhost:3000/devices"
{}

部分的にはできないか。

# curl -X PATCH -H "Content-Type: application/json" -d '{
> "uuid": "25a344a0-6c85-48cd-a153-d912d3c7614a",
> "mac": "a5:ba:23:f6:25:48",
> "ipv4": "192.168.0.1",
> "id": 30001
> }' "http://localhost:3000/devices"
{}

あら、全部もダメそう。

# curl -X GET "http://localhost:3000/devices/30001"
{
"uuid": "25a344a0-6c85-48cd-a153-d912d3c7614a",
"mac": "a5:ba:23:f6:25:48",
"ipv4": "210.133.43.253",
"id": 30001
}

書き換わってないね。
なんか間違っているかな?
消してから書けってことかな?
今回は更新はないからいいか。

レコードの削除

# curl -X DELETE -H "Content-Type: application/json" "http://localhost:3000/devices/30001"
{}
# curl -GET "http://localhost:3000/devices/30001"
{}