Node.js のフレームワーク「Fastify」とキーバリューストア「keyv」を組み合わせて試す（JSON を GET・POST で扱う）

過去に別々に試したことがあるフレームワーク「Fastify」とキーバリューストア「keyv」を、組み合わせて試してみるという内容です。

- [Node.js のフレームワークの Fastify と WebSocket を利用可能にする fastify-websocket を軽く触ってみる - Qiita](https://qiita.com/youtoy/items/7c5a318278e397602b76)
- [Node.js用のシンプルなキーバリューストア「keyv」を試す（データの保持はメモリ・SQLite） - Qiita](https://qiita.com/youtoy/items/6137b6d417b1ab1a31e4)

## Fastify で GET・POST を試す（JSON のやりとり）
### GET を扱う
Fastify で GET ＋ JSON を利用する方法は、[公式の「Getting Started > Your first server」](https://www.fastify.io/docs/latest/Guides/Getting-Started/#your-first-server)にも書かれており、冒頭に掲載した記事でも試しています。

流れとしては、 npmコマンドで Fastify をインストールし、以下のプログラムを動かすだけです（※ 公式で書かれている「async/await を使わないもの」と「async/await を使うもの」を両方掲載しています）。

```javascript
const fastify = require("fastify")({
  logger: true,
});

fastify.get("/", function (request, reply) {
  reply.send({ hello: "world" });
});

fastify.listen(3000, function (err, address) {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
});
```

```javascript
const fastify = require("fastify")({
  logger: true,
});

fastify.get("/", async (request, reply) => {
  return { hello: "world" };
});

const start = async () => {
  try {
    await fastify.listen(3000);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};
start();
```

あとは、ブラウザや curl などで `http://127.0.0.1:3000` に対して GETリクエストを送るだけです。問題なく動作していれば、レスポンスとして `{"hello":"world"}` という内容を取得できます。

### POST を扱う
Fastify で POST を扱う場合の話ですが、以下の記事を見てみると JSON を使うのであればシンプルに実現できるようです。

- [fastify json形式のPOSTデータ受け取り - Symfoware](https://symfoware.blog.fc2.com/blog-entry-2491.html)
- [fastifyでPOSTデータ受信時、FST_ERR_CTP_INVALID_MEDIA_TYPE - Symfoware](https://symfoware.blog.fc2.com/blog-entry-2490.html)

以下のようなプログラムを動作させてみました。こちらは先ほどと異なり、ブラウザでのアクセスで試すということはできません。

```javascript
const fastify = require("fastify")({
  logger: true,
});

fastify.post("/", async (request, reply) => {
  const body = request.body;
  console.log(body, body.name);
  return body;
});

const start = async () => {
  try {
    await fastify.listen(3000);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};
start();
```

そこで、curl を使って POSTリクエストを送ってみます。

```bash
$ curl -X POST -H "Content-Type: application/json" -d '{"name":"山田太郎", "id":"1"}' http://127.0.0.1:3000
```

curl のレスポンスは「POST で送信した JSON」になり、ログには「その JSON」と「JSON の name の部分」が出力されるのが確認できると思います。

## Fastify と keyv を組み合わせる
それでは今度は、Fastify と keyv を組み合わせてみます。試しに、以下の動作をするようなものにしてみました。

- やりとりするデータは JSON
   - フォーマットは `{"key":"【キーの文字列】", "value":"【メインのデータ】"}`
- POST でデータを送る
   - リクエストボディで JSON を送信
- GET で保存されたデータを取得する
   - クエリ文字列で取得するデータのキーを指定

### 作成したプログラム
そして、以下のプログラムを作って動かしてみました。動作させる前に、npmコマンドで keyv を追加でインストールしてください。

```javascript
const fastify = require("fastify")({
  logger: true,
});
const Keyv = require("keyv");
const keyv = new Keyv();

keyv.on("error", (err) => console.log("Connection Error", err));

fastify.post("/", async (request, reply) => {
  const body = request.body;
  await keyv.set(body.key, body.value);
  return body;
});

fastify.get("/", async (request, reply) => {
  const key = request.query.key;
  const value = await keyv.get(key);
  console.log(value);
  reply.send(value);
});

const start = async () => {
  try {
    await fastify.listen(3000);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};
start();
```

### 動作確認
以下は動作確認用のコマンドです。

#### データの送信
curl で以下を実行。

```bash
$ curl -X POST -H "Content-Type: application/json" -d '{"key":"aaa", "value":"テスト1"}' http://127.0.0.1:3000

$ curl -X POST -H "Content-Type: application/json" -d '{"key":"bbb", "value":"テスト2"}' http://127.0.0.1:3000
```

#### データの取得
ブラウザで `http://127.0.0.1:3000/?key=aaa` や `http://127.0.0.1:3000/?key=bbb` にアクセス。
または、curl で以下を実行。

```bash
$ curl "http://127.0.0.1:3000/?key=aaa"

$ curl "http://127.0.0.1:3000/?key=bbb"
```

指定したキーによって、レスポンスが「テスト1」や「テスト2」になるのが確認できると思います。