Redisを用いたキャッシュの効果を計測する

[Redis Caching in Node.js](https://www.youtube.com/watch?v=oaJq1mQ3dFI) のメモです。

まずは以下のようにRedisを用いずにGitHubのレポジトリの数を表示します。

```javascript
const express = require("express");
const fetch = require("node-fetch");

const PORT = process.env.PORT || 5000;

const app = express();

function setResponse(username, repos) {
  return `<h2>${username} has ${repos} Github repos</h2>`;
}

async function getRepos(req, res, next) {
  try {
    console.log("Fetching Data...");

    const { username } = req.params;

    const response = await fetch(`https://api.github.com/users/${username}`);

    const data = await response.json();

    const repos = data.public_repos;

    res.send(setResponse(username, repos));
  } catch (err) {
    console.error(err);
    res.status(500);
  }
}

app.get("/repos/:username", getRepos);

app.listen(5000, () => {
  console.log(`App listening on port ${PORT}`);
});
```

http://localhost:5000/repos/wafuwafu13 にアクセスして計測すると、421msかかっていました。
![スクリーンショット 2021-01-07 19.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/84bd6485-cf88-6afe-5672-054dd149ac60.png)

リロードする度にAPIを叩いているので何度しても結果はあまり変わりません。
![スクリーンショット 2021-01-07 18.56.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/15ccc555-f1ed-aa1d-2127-7a373cd493c8.png)

次に、Redisを用いてレポジトリの数をキャッシュしてみます。

```javascript
const express = require("express");
const fetch = require("node-fetch");
const redis = require("redis"); // 1

const PORT = process.env.PORT || 5000;
const REDIS_PORT = process.env.PORT || 6379; // 2

const client = redis.createClient(REDIS_PORT); // 3

const app = express();

function setResponse(username, repos) {
  return `<h2>${username} has ${repos} Github repos</h2>`;
}

async function getRepos(req, res, next) {
  try {
    console.log("Fetching Data...");

    const { username } = req.params;

    const response = await fetch(`https://api.github.com/users/${username}`);

    const data = await response.json();

    const repos = data.public_repos;

    client.setex(username, 3600, repos); // 4

    res.send(setResponse(username, repos));
  } catch (err) {
    console.error(err);
    res.status(500);
  }
}

// 5
function cache(req, res, next) {
  const { username } = req.params;

  client.get(username, (err, data) => {
    if (err) throw err;

    if (data !== null) {
      res.send(setResponse(username, data));
    } else {
      next();
    }
  });
}

app.get("/repos/:username", cache, getRepos); // 6

app.listen(5000, () => {
  console.log(`App listening on port ${PORT}`);
});
```
1でRedisをインポートして、2,3でポートの設定をします。
4の[setex](https://redis.io/commands/setex)で、`username`をkey,`repos`をvalueにして3600秒間で設定します。
`get username`をするとvalueが取り出せるようになります。
![スクリーンショット 2021-01-07 19.04.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/a2fabc63-3e49-432f-2228-ac139aee15ad.png)
5の[get](https://redis.io/commands/get)でそのvalueを取り出し、レスポンスを返しています。
6でその関数を呼び出しています。
結果は、1回目のロード時はキャッシュが効いていないので変わらないですが、2回目のリロードからはキャッシュが効くので8msとだいぶ速くなります。
![スクリーンショット 2021-01-07 19.01.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/f281d724-6ef2-ab6c-918b-e709fcc415a3.png)
APIを叩きにいっていないのがわかります。
![スクリーンショット 2021-01-07 18.59.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/33d00308-a131-c430-6065-a97710172b37.png)
[FLUSHALL](https://redis.io/commands/flushall)で削除した直後の１回目はキャッシュが効かないのでまた遅くなります。
![スクリーンショット 2021-01-07 19.06.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/0010cc9d-d5e6-bf85-672f-20a34ef55043.png)