【IBM Cloud】Databases for RedisとNode.jsの接続

# Databases for Redisの導入

IBM Cloud上で作成したDatabases for RedisをNode.jsと繋げる方法を記します。

## インスタンスの作成

IBM Cloud上でDatabase for Redisのインスタンスを作成します。
まずはカタログからDatabases for Redisを選択しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/3b221e00-053a-cc86-7de0-e4358bacf1cd.png)
Service Detailsは適当なものを設定し、Createしましょう。

リソースリストから見て、作成したRedisがアクティブになっていれば準備OKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/7446da40-e96f-9369-7c9d-8d7e5bd2eab2.png)
名前をクリックして開くと、Overviewが表示されます。



## Node.jsからの接続

Overviewの一番下までスクロールすると、Quick startのガイドがあります。基本的にはこれに従えば大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/e8f94d65-5c51-aba8-0250-04d3bb1c377b.png)

### 接続先URLの設定

画面右下のService Credentialをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/e0bf796a-25a3-ba6f-8d5c-198366c328a4.png)
Service credentialsに一つKeyが作成されているはずなので、それを展開します（なかったらNew credentialをクリックして作成します）。

connection, cli, arguments,に-uとしてrediss接続用のURL（`rediss://{user}:{pass}@{host}:{port}`の形）が載っているのでコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/b24d1906-947d-7cdb-463c-6281dd835706.png)

また、user, passに関しても環境変数を設定して分けたい場合は、（上のURLから抜き出しても良いですが、）もう少し下へスクロールするとpassword, usernameという欄があるのでこちらからコピーしても構いません。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/cf836537-620a-77f7-d066-bd1f6bffdedf.png)

Node.js側にて`settings_redis_url`を定義し、
環境変数に先程コピーしたURLを設定しましょう。
```console:環境変数の設定
REDIS_DATABASE_URL=rediss://ibm_clo~~1a3ba42:a913~~5e13@d9f8~~
```

```javascript:dotenvを用いて環境変数から値を読み込みます
const settings_redis_url = 'REDIS_DATABASE_URL' in process.env ? process.env.REDIS_DATABASE_URL : '';
```

### 証明書の設定
[先程のQuick start](#nodejsからの接続)にある、`1. Get the TLS Certificate`から証明書テキストをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3363316/46983b86-d077-7483-48df-9f626a612d87.png)
証明書テキストを環境変数として設定します。

改行を含む形ですが、ダブルクォーテーションで囲えば大丈夫です。
少なくともローカルで`npm start`する分には正しく動作しました。
```console
REDIS_CERTIFICATE="MIIDHTCCAgWgAw~~
~~~
~~~
-----END CERTIFICATE-----"
```

#### 証明書テキストを環境変数に設定する際の注意
今回はCodeEngine上にアプリケーションをデプロイする予定なので、証明書テキストの文字列を少し加工します。（詳しい話は以下の記事をご覧ください。）

https://qiita.com/tsukinomi/items/18ed6c0f32fe8c9b9892

改行を`\n`に置き換え、ダブルクォーテーションでは囲わずに環境変数へ設定すると、以下のような形になります。
```console:環境変数の設定
REDIS_CERTIFICATE=MIIDHTCCAgWgAw~~\n~~\n~~\n-----END CERTIFICATE-----
```
以下のように証明書テキストを読み込んだら、正規表現を用いて文字列を置き換え、改行コードとして認識させます。
```javascript
const redis_cert = 'REDIS_CERTIFICATE' in process.env ? process.env.REDIS_CERTIFICATE : '';
redis_cert = redis_cert.replace(/\\n/gm, "\n")
```

### Redis接続のコード

以上環境変数が設定できたら、接続先の設定を`redis.createClient`で作成し、`redisClient.connect()`で接続します。

```javascript
// 環境変数より変数へ代入
const settings_redis_url = 'REDIS_DATABASE_URL' in process.env ? process.env.REDIS_DATABASE_URL : '';
const redis_cert = 'REDIS_CERTIFICATE' in process.env ? process.env.REDIS_CERTIFICATE : '';
redis_cert = redis_cert.replace(/\\n/gm, "\n")

//. Redis
var redis = require( 'redis' );
var redisClient = null;
if( settings_redis_url ){
  // 接続先の設定
  redisClient = redis.createClient( {
    url: settings_redis_url, // 接続先のURL
    legacyMode: false,
    tls: {},
    socket: {
      tls: true,
      rejectUnauthorized: false,
      cert: redis_cert, // 証明書テキスト
    }
  } );
  // 接続
  redisClient.connect();
  console.log( 'redis connected' );

  redisClient.on( 'error', function( err ){
    console.error( 'on error redis', err );
  });
}
```
ちなみに切断時には自動で再接続されるらしいので、PostgreSQLのようにreconnectの関数を作る必要はない…らしいです。