REST ClientからCloudantを操作する

# 前置き
## そもそもCloudantはブラウザから操作できるのでは？
そんな疑問を持つ方がいるのも当然で、IBM CloudでCloudantのサービスを開始したら、ブラウザでDBを作成したり、ドキュメントを作成したりすることもできます。

そう、IBM Cloudにログインできれば。。。

## とりあえず削除したいDocumentがDBの中にあるんだ！
自分のアカウントにログインができなくなっているけれど、アカウントが完全に消えているわけではなく、アカウントに招待している人に確認してもらったら、問題なく私のアカウントの環境に入れるらしい。

今、ローカルで作成しているアプリがあるのだけれど、作成途中で動かしたら変なDocumentがCloudantに保存されてしまい、消そうにもブラウザからログインできないので、簡単に消せない。
コード自体は `Node.js` で記述しているので、自分でDocumentを取得して削除する処理を書いても良いけど、もう少し簡単に実現したい。

## VSCodeに導入しているREST Clientを使ってみよう
※REST Clientの紹介として、こちらの記事がおススメです
[VS Code上でHTTPリクエストを送信し、VS Code上でレスポンスを確認できる「REST Client」拡張の紹介](https://qiita.com/toshi0607/items/c4440d3fbfa72eac840c)

Cloudant のDocsを確認しても、ネットで検索してもcurlの操作方法ばかりでREST Clientでの操作方法の記事があまり見つかりませんでした。
もちろんVSCode使いながらターミナル開いてcurl使うのも良いのですが、個人的にREST Clientはコード書く環境に `.rest` 拡張子でファイルを保存して、そこに通信したい内容を記述すれば `Ctrl + Shift + R` で通信できたりと、curlよりお手軽なイメージを持っています。どちらが良いかは、個人の嗜好に依ると思いますので、ここでは議論しません。

# 本題
## 実行環境
`OS` Windows10
`VScode` 1.45.0
`REST Client` 0.23.2

## 必須の情報
Cloudantに接続するための `認証情報` は必ず持っていてください。
`apikey` と `url` が把握できていれば操作可能です

## token の取得
新規ファイルを`.rest`の拡張子で任意の場所に保存して、以下の`apikey`を差し替えて記述し、先頭のPOST～末尾の/jsonまで選択した状態で`Ctrl + Alt + R`で通信してみてください

```Nginx:REST-Client
POST https://iam.bluemix.net/identity/token
        ?grant_type=urn:ibm:params:oauth:grant-type:apikey
        &apikey= あなたのapikeyを指定してください
Content-Type: application/x-www-form-urlencoded
Accept: application/json
```
指定に問題がなければ以下のような応答が得られるはずです。
※`access_token`　`refresh_token` 共に1000Byte以上もあり応答結果は見にくいので注意してください

```json:Response
{
  "access_token": "eyJraWQiOiIyMDIwMDUyNTE4MzAiLCJhbGciOiJSUzI...",
  "refresh_token": "OKBq26b8c8596uy7JHVKIACXYS53L5a2omc8yHgE1p_CG6W177kiPmZuWjmI8...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expiration": 1591367976,
  "scope": "ibm openid"
}
```
以後、この`access_token`の情報は使い続けるので、変数化しておきましょう。
※このtokenは3600秒(1時間)で失効するので注意してください

```Nginx:REST-Client
@token = eyJraWQiOiIyMDIwMDUyNTE4MzAiLCJhbGciOiJSUzI...
```

## DBの一覧取得
ソースコードを見れば、操作していたDB名は取得できますが、REST ClientからDBの一覧を取得しましょう。
最初に、リクエスト送信先のURLは何度も利用するので、tokenを取得した`.rest`のファイルに以下の変数を作成しておきます。これは、Cloudantの認証情報に含まれるURLのそのままでも良いですし、`https://`の後ろから`@`まで(ユーザーIDとパスワード)を消したものでも良いです。
### 認証情報そのまま

```Nginx:REST-Client
@baseurl = https://xxxxx-bluemix:xxxxx@xxxxx-bluemix.cloudantnosqldb.appdomain.cloud
```
### ユーザIDとパスワードを消したもの

```Nginx:REST-Client
@baseurl = https://xxxxx-bluemix.cloudantnosqldb.appdomain.cloud
```

それでは、`.rest`のファイルに、以下を記述して、テキストを選択した状態で `Ctrl + Alt + R` で通信してみましょう。
※`{{ }}`で変数の内容を呼び出しています

```Nginx:REST-Client
GET {{baseurl}}/_all_dbs
Authorization: Bearer {{token}}
Accept: application/json
```

記述や通信に問題がなければ、Cloudantに保存されたDBの一覧が取得できるはずです。

```json:Response
[
  "_replicator",
  "xxxxxx-docs",
  "yyyyy-docs",
  "zzzzz-docs"
]
```

## 指定したDBのDocumentを確認
例えば、`xxxxx-docs`DBの中のDocumentを確認したい場合は、以下を実行してみましょう。
まず、このDBでの操作を何度か行うのであれば変数化しておくと良いです。

```Nginx:REST-Client
@db = xxxxx-docs
```
そして、DB内のDocumentを取得するには、以下の通信になります。

```Nginx:REST-Client
GET {{baseurl}}/{{db}}/_all_docs
Authorization: Bearer {{token}}
Accept: application/json
```

```json:Response
{
  "total_rows": 11,
  "offset": 0,
  "rows": [
    {
      "id": "1bd18004e4788243e827df8c6e1c47f0",
      "key": "1bd18004e4788243e827df8c6e1c47f0",
      "value": {
        "rev": "1-6bfc36e2b72ced7552f551fcef5c5a56"
      }
    },...
  ]
}
```
これだとDocumentの中身がわからないですね、パラメータを追加しましょう。

```Nginx:REST-Client
GET {{baseurl}}/{{db}}/_all_docs
    ?include_docs=true
Authorization: Bearer {{token}}
Accept: application/json
```

```json:Response
{
  "total_rows": 11,
  "offset": 0,
  "rows": [
    {
      "id": "1bd18004e4788243e827df8c6e1c47f0",
      "key": "1bd18004e4788243e827df8c6e1c47f0",
      "value": {
        "rev": "1-6bfc36e2b72ced7552f551fcef5c5a56"
      },
      "doc": {
        "_id": "1bd18004e4788243e827df8c6e1c47f0",
        "_rev": "1-6bfc36e2b72ced7552f551fcef5c5a56",
        "date": "2020-05-28T22:00:00.000Z",
        "link": "https://www.ibm.com/cloud/blog/",
        "status": "done"
      }
    },...
  ]
}
```
これで、Documentの中身まで見えるようになったはずです。

さて、私が消したいDocumentが見つかりました。
この時、対象のDocumentの`_id` `_rev` を記録しておきましょう。
変数に設定するのも良いです。

```Nginx:REST-Client
@id = 6ffb78d3f95d822385c1dde9557XXXXX
@rev = 1-3a4eb420b45ac0d2972037e2865XXXXX
```

## 指定したDocumentを確認して削除
まず、消したいDocumentが正しいか確認しましょう。SQLでDelete実行する前に条件が正しいかSelectするようなものです。

```Nginx:REST-Client
GET {{baseurl}}/{{db}}/{{id}}
Authorization: Bearer {{token}}
Accept: application/json
```

```json:Response
{
  "_id": "6ffb78d3f95d822385c1dde9557XXXXX",
  "_rev": "1-3a4eb420b45ac0d2972037e2865XXXXX",
  "date": "2020-05-28T22:00:00.000Z",
  "link": "https://www.ibm.com/cloud/blog/",
  "status": "done"
}
```
目的のDocumentが指定できたので削除しましょう。revisionの指定を忘れないようにしてください。

```Nginx:REST-Client
DELETE {{baseurl}}/{{db}}/{{id}}
    ?rev={{rev}}
Authorization: Bearer {{token}}
Accept: application/json
```
応答で `"ok":true` が返ってきたらDocumentが削除されています。

```json:Response
{
  "ok": true,
  "id": "6ffb78d3f95d822385c1dde9557XXXXX",
  "rev": "2-c73f3d48fa50b12de6890cd36c4YYYYY"
}
```

## DBにDocumentを追加
既に目的は達しましたが、REST ClientからDBに任意のDocumentを追加する方法も紹介します。
`PUT`を利用してDocumentを追加しますが、以下のように記述します。
2点の注意が必要です
1. `abc`の部分は任意のDocumentの`ID`の指定が必要です。他のDocumentと重ならないようにしてください。
2. REST Clientで指定しているヘッダー部分と、追加したいDocumentのJSONの開始位置の間には、空行を1つ設けるようにしてください。

```Nginx:REST-Client
PUT {{baseurl}}/{{db}}/abc
Authorization: Bearer {{token}}
Accept: application/json

{
  "key":"value",
  "test-key":"test-value"
}
```
応答で `"ok":true` が返ってきたらDocumentが追加されています。

```json:Response
{
  "ok": true,
  "id": "abc",
  "rev": "1-2a7680ee5848a07cc7c47fce3059f4eb"
}
```
追加したDocumentが参照できてることを確認しましょう。

```Nginx:REST-Client
GET {{baseurl}}/{{db}}/{{id}}
Authorization: Bearer {{token}}
Accept: application/json
```


```json:Response
{
  "_id": "abc",
  "_rev": "1-2a7680ee5848a07cc7c47fce3059f4eb",
  "key": "value",
  "test-key": "test-value"
}
```

# さいごに
結局、REST ClientでCloudantを操作する方法を調べることに時間を多く割いてしまい、`Node.js`で処理を書いたほうが圧倒的に早かったのですが、非常に勉強になりました。
誰かREST Clientを利用して、CloudantやCouchDBにアクセスしてみたい方の一助になれば幸いです。