Node-REDでCloudantの添付ファイル作成


Node-RED上でCloudantのドキュメントに、画像ファイルを添付ファイルとしてアップロードしたかったのですが、それ用のノードがありませんでした。
そこで、http requestノードを使って、CloudantのREST API に対してリクエストするかたちで作ってみました。

# CloudantのAttachments

添付ファイルは、バイナリーで保存する方法と、ドキュメントのinline要素としてBASE64で保存する方法があります。

今回は、バイナリーで保存します。

添付ファイルは、既存ドキュメントに対して作成することになります。REST APIのパスにドキュメントの「_id」が入っています。またリクエストパラメータで「_rev」を入れる必要があります。
>To create a new attachment on an existing document, or to update an attachment on a document, make a PUT request with the document’s latest _rev to https://$USERNAME.cloudant.com/$DATABASE/$DOCUMENT_ID/$ATTACHMENT. The attachment’s content type must be specified using the Content-Type header. The $ATTACHMENT value is the name by which the attachment is associated with the document.

![image](https://qiita-image-store.s3.amazonaws.com/0/100414/68545f96-ef69-56ea-f4b8-539f1443da7e.png)

https://docs.cloudant.com/attachments.html

# （サンプル）Node-REDフロー

putでドキュメントを作成するフロー、putで添付ファイルを作成するフローの２つに分けて作成しました。

+ ドキュメント作成　PUT /api/user
+ 添付ファイル作成　PUT /api/user/:_id/attachment


## ドキュメント作成
既存のノードを使って、シンプルにデータ保管。

![image](https://qiita-image-store.s3.amazonaws.com/0/100414/011c26a5-70c2-1ae2-856b-f2a270a6d040.png)

### フローのJSON
+ 「insert user」ノードのサービスは自分のものを設定して使用。

```json
[{"id":"13019c96.565263","type":"http in","z":"7e517ea1.72905","name":"","url":"/api/user","method":"put","swaggerDoc":"","x":120,"y":129.33332061767578,"wires":[["7cecee77.70c7a","4161ba4.3316b44"]]},{"id":"7cecee77.70c7a","type":"cloudant out","z":"7e517ea1.72905","name":"insert user","cloudant":"","database":"user","service":"","payonly":true,"operation":"insert","x":313,"y":129.33330535888672,"wires":[]},{"id":"4161ba4.3316b44","type":"http response","z":"7e517ea1.72905","name":"","x":296,"y":164.99999237060547,"wires":[]},{"id":"e0c84058.ac275","type":"comment","z":"7e517ea1.72905","name":"ドキュメント作成","info":"","x":128,"y":79.99999237060547,"wires":[]}]
```

### リクエスト実行（ドキュメント作成）
POSTMANからリクエスト実行。
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/f9fd98ec-a4c7-4674-2ecd-c5b8e1b1ea3a.png)

Cloudantのコンソールでドキュメントを確認。
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/2d95270e-bf1a-5140-3900-38b46869a84b.png)


## 添付ファイル作成

ます、Node-REDへのリクエストのパスの{_id}をキーにして、userデータベースを検索し、「_rev」を入手します。その後、「_rev」も含めて、添付ファイル作成用にリクエストを作って、CoudantのREST APIを実行。

![image](https://qiita-image-store.s3.amazonaws.com/0/100414/2017ff6f-9a8a-523c-e08b-8740c974171e.png)

### フローのJSON
+ 「search user」ノードのサービスは自分のものを使用。
+ 「Cloudantへのリクエスト準備」ノードの「url」は、CloudantのVCAP_SERVICESをコピペ
+ 「PUT Attachment To user」ノードで、「Use basic authentication」オプションを設定。Username, Passwordは、CloudantのVCAP_SERVICESをコピペ

```json
[{"id":"c3f8eebe.36d51","type":"http request","z":"92620c6b.387a5","name":"PUT Attachment To user","method":"PUT","ret":"obj","url":"","tls":"","x":804.8331909179688,"y":393.6666564941406,"wires":[["30a4dbe9.dc77a4","2a578f04.885aa"]]},{"id":"30a4dbe9.dc77a4","type":"http response","z":"92620c6b.387a5","name":"","x":993.8333129882812,"y":393.3333435058594,"wires":[]},{"id":"de0dece1.8432a","type":"cloudant in","z":"92620c6b.387a5","name":"search user","cloudant":"","database":"user","service":"nodered-test-shimac-3848-cloudantNoSQLDB","search":"_id_","design":"","index":"","x":700.8333129882812,"y":286.6667175292969,"wires":[["4425dd96.3af944","d35e5262.63a4a"]]},{"id":"dee89630.5435e8","type":"http in","z":"92620c6b.387a5","name":"","url":"/api/user/:_id/attachment","method":"put","swaggerDoc":"","x":242.83334350585938,"y":286.33338928222656,"wires":[["83b780f8.65ca5","4ee12752.6f8f98"]]},{"id":"83b780f8.65ca5","type":"function","z":"92620c6b.387a5","name":"パスから_id 取得","func":"msg.payload._id = msg.req.params._id;\nreturn msg;","outputs":1,"noerr":0,"x":514.8333740234375,"y":286.6667175292969,"wires":[["de0dece1.8432a"]]},{"id":"2a578f04.885aa","type":"debug","z":"92620c6b.387a5","name":"ent put attachment","active":true,"console":"false","complete":"payload","x":1032.8333129882812,"y":339.00006103515625,"wires":[]},{"id":"4ee12752.6f8f98","type":"debug","z":"92620c6b.387a5","name":"start put attachment","active":true,"console":"false","complete":"payload","x":534.8333740234375,"y":248.0000762939453,"wires":[]},{"id":"be9657ea.a90998","type":"comment","z":"92620c6b.387a5","name":"添付ファイル作成","info":"","x":199,"y":239.33338165283203,"wires":[]},{"id":"4425dd96.3af944","type":"function","z":"92620c6b.387a5","name":"Cloudantへのリクエスト準備","func":"// Cloudant検索結果から_id、_revをセット\nvar _id = msg.payload._id;\nvar _rev = msg.payload._rev;\n\n// VCAP_SERVICEのCloudantのurl\nvar url = \"自分のurl\";\n// データベース名\nvar db_name = \"user\";\n// 添付ファイル名\nvar file_name = _id + \".jpeg\";\n\n// 添付ファイル作成用のCloudantのRESTAPIのパス\nmsg.url = url + \"/\" + db_name + \"/\" + _id + \"/\" + file_name + \"?rev=\" + _rev;\nmsg.headers = {\n    \"Content-Type\": \"image/jpeg\"\n};\n// ペイロードに画像ファイルのバイナリをセット\nmsg.payload = msg.req.body;\n\nreturn msg;","outputs":1,"noerr":0,"x":547.9999084472656,"y":394.3334045410156,"wires":[["c3f8eebe.36d51"]]},{"id":"d35e5262.63a4a","type":"debug","z":"92620c6b.387a5","name":"search user","active":true,"console":"false","complete":"payload","x":846.9999694824219,"y":243.33338165283203,"wires":[]}]
```

### リクエスト実行（添付ファイル作成）
POSTMANからリクエスト実行。
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/ddf960de-7967-c5ec-11c9-85aec4da4d81.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/961cc193-14cd-4763-9872-6289020fedca.png)

Node-REDのデバッグログ
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/4561dd38-db44-89b7-a708-9f4f5c4a4ed1.png)

### 添付ファイルの確認
Cloudantのコンソールをみると、ドキュメントに「_attachment」が追加されたことが確認できます。
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/9aba03cb-6487-2880-27a7-a3e7911cbc78.png)

「View Attachments」で、画像ファイルを選択してみると、
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/451f4994-01c8-ea9f-8e27-d5664159760e.png)

無事、画像ファイルを参照することができました。
![image](https://qiita-image-store.s3.amazonaws.com/0/100414/f830def1-9244-e8fe-d55b-90bae7aa2b42.png)

# おわり
次回は、Node-RED上で、この画像ファイルを取得して、WatsonのVisual Recognitionに投げてみたいと思います。