私が Node-RED を頻繁に利用するようになったきっかけとハッカソンでの Node-RED 利用について考察

今回の記事は、私が Node-RED を頻繁に利用するようになったきっかけをネタにしたいと思います。またハッカソンでのNode-RED利用を考察します。

## Emerging Technology って？

Node-REDは "Emerging Technology" という部署が開発したと聞いたことがあるかも知れません。

製品開発では、初めてのリリースの場合、開発者がかかわることが多いです。製品の最終局面（EOL - End of Life) でもそれが見られます。

![developer-involvement.png](https://qiita-image-store.s3.amazonaws.com/0/74673/fc20ee6e-8c1f-3239-6a4a-15a2424fd089.png "製品開発局面")

製品が出たばかりの場合は、情報も少ないので、製品を熟知している開発者が直接お客様対応をしたりし、徐々にいろんな人にスキル移転をはかります。情報が充分にいきわたると、開発者はもとの開発に専念するのですが、やがて製品は EOL (End of Life)を迎えます。EOL を迎える場合は、新バージョン製品や代替製品について、お客様担当営業と話したり、あるいは直接お客様と話をしてそれらに移行してもらいます。IBMでは、よく "Emerging Technology Team"　とか "SWAT" チームという開発者組織が特別に編成され対応にあたります。

Node-RED も "Emerging Technology"チームが担当していますよね！


##従来の製品の啓蒙活動

IBM社では、ソフトウェア製品を開発しています。営業が製品をお客様に紹介する場合には、製品の特徴や、期待される効果などを盛り込み提案しますが、このときに通常 **評価** というプロセスが発生します。大体、この評価プロセスは１週間から２週間程度が多いようです。場合によっては数ヶ月規模ということもあるでしょう。評価のための無料トライアルは製品によってばらつきがありますが、Bluemixの場合は30日間無制限で使えます。その後も、無料枠を用意しているので評価をある程度継続できます。ある製品は開発者にかぎっては永久につかえるというのもあります。後者のケースは最近増えていますね。

まったく新しい製品の場合であったり、以前のバージョンからの更新があった場合には、開発者もお手伝いしミスがないようにするのが一般的であり、ワークショップという形で、製品の主な機能や、評価の方法などをガイドします。よくハンズオンセッションなどもやってますよね。もしくは、お客様が評価したいポイントを決め、それを実証する Proof of Concept (実証実験)を行うこともあるでしょう。これも大体２週間程度です。この程度の期間であれば、製品の特徴をつかむことは可能であり、営業が提案した内容を深く知ることができるため、お客様も納得しやすいです。

ところがクラウドはまったく異なります。

## クラウドの評価は２週間でできるのか？

クラウドにはインフラが存在し、１００を超えるソフトウェアがサービスとして存在します。ここで課題が立ちはだかります。

> ２週間でクラウドを評価できるか？
 
部署がかわってクラウド担当になった営業から言われるのが「クラウドはどう売ったらいいのかわからない」です。慣れてくればそうでもないのですが、特定のソフトウェア製品分野からクラウド営業に配置転換して来た人がぶつかる問題がこれです。今までどおりの製品売りの概念を持ち込むとクラウドの場合とたんに破綻します。特に、評価となると困難を伴います。単純にインフラを立てるだけで、評価といえるか？あるはソフトウェアを導入して使っただけで、評価といえるのか？そもそも１００あるサービスなんて全部試すのか？　

そこで、開発部隊としてもなんとか営業を支援して、なんとか２週間程度でクラウドを評価できる方法を見つけないといけません。しかもわりと厳しい前提条件があります。

- 予算をもっている人は必ずしもプログラミングに長けているわけではない
- そもそもクラウドの評価、特に PaaS は基準が難しい

IaaSの場合は、コストメリット、パフォーマンス、スケールメリットが評価ポイントになりやすいですが、PaaS の場合は評価基準が明確ではありません。アプリケーションが迅速にデプロイできます！といっても予算をもっている人から言わせると、「でっ！」といわれるのが落ちですね。クラウド、特にPaaS評価ポイントは標準なものはないのですが、検索するといくつか出てきます。ただこの記事は、 Node-RED ですので、その点には深く入らないことにします。

IBM Bluemix の場合、RapidAppsというサービスがありこれを使うと迅速にアプリケーションが作成できたので良かったのですが,ある時諸事情で開発がとまってしまいました。営業から、「なんとかならないですかね～」といわれるのも時間の問題でした。これが Node-REDと深く付き合うようになったきっかけです。


## Node-RED を使う案を検証してみた

営業からは、Node-REDをうまく使えないか？といわれ、いくつか議論しました。そこでNode-RED が当時、どのように使われているかを調査することにしました。調べてみると、当時の調査時点では、ほぼ IoT　のサービスと接続して、温度などのセンサーデータを DEBUG タブに出力しているのがほとんどであり、そこから脱し切れていないようでした。

皆さんご存知のように、Node-RED はさまざまなインターネット上に発生するイベントを加工処理するのが得意です。PaaS の場合、新しいアイデアを形にして、SoE (Systems of Engagement)の世界を切り開くものであると説明されていることが多いと思います。

そこで自分なりに、テーマを決めて２週間でできるか挑戦してみました。

たとえば、テーマとしては、

- 自分のいる場所から情報を入れれば近くの旬な情報を教えてくれる
- 近くのATM場所を教えてくれる

などの "Context Aware"(コンテキストアウェア)なアプリケーション

- 自分たちの製品の評判を分析するアプリケーション
- 他社とのイメージ比較分析を実施するもの

などの分析アプリケーションなど、少しテーマを決めて、実際に短期間で開発できるか？に挑戦してみました。結果としては、ほぼ大体のアプリケーションが**２日** 、少し複雑なものでも**４日** 程度あれば開発ができることがわかりました。通常サーバーサイドの開発は、APIの調査をはじめとして、REST API のコールや単体試験の準備など時間を要します。Node-RED は多くのAPIをカプセル化してくれるので、この点作業が大幅に時間短縮となります。

さらには、サーバーサイドの処理説明も Node-RED のフローがわかりやすいです。たとえば、こんな感じです。

> ユーザーの位置情報はGPS から取得されたものを Node-RED が受け取ります。これをインプットとして、一押し商品を検索します。これがそのノードです。検索がおわったら、Google Map に店の位置と連絡先、またその商品情報もユーザーに伝えます。そのあたりの処理のノードがこれとこれです。

これを営業と少し議論したときに、これだったら説明しやすいかもしれないという話になりました。つまり、プログラミングに長けていなくても、処理は説明しやすいし、お客様も理解しやすい。なによりもお客様に少しアイデアを出してもらって、ではこうすればできますという実証も短期間でできる。つまり制約条件である：

> 予算をもっている人は必ずしもプログラミングに長けているわけではない

が解決できるわけです。かつ、時間制約内で検証できる可能性が大きい。

評価はどうだろう？　

> そもそもクラウド(PaaS)の評価って基準が難しい

これについて、日本Cloud Foundaryグループ内でもディスカッションがありました。まだ公式なドキュメントはないですが、ひとつの案として アイデア→プロトタイプ実装が如何に迅速にできるかを評価基準にしてもらうというのはどうか？という案がでています。いわゆる企業内ハッカソンを実施するという提案です。ここはお客様との合意が必要なところです。

もちろんこれ以外の評価もあると思われますが、そもそもお客様の課題は**どのようにビジネスを創出するか、これを迅速にリリースして、よりすばやく価値をエンドユーザーに届けるか**ということになるでしょう。ここは合意しやすいのではないでしょうか。

てなわけで、Node-RED をいろいろいじるうちにだんだん良くわかってきたので、ためしに PaaS勉強会で発表してみようかな？という段取りになり[発表もしました](http://paas.connpass.com/event/17139/)、より多くの人に Node-RED のよさがわかってもらえたかな？と思っています。

ものすごく盛り上がって、Node-RED ユーザー会ができたのは非常にうれしく感じています。

## 実装の具体的なやり方

さて、少しは技術情報もないといけないかなと思うので、技術ネタを。上記に、ハッカソンを実施する時に、Node-RED が使えるという話をしましたが、具体的にどうやるかについて、僕個人の方法をご紹介したいと思います。ハッカソンで困る点は、役割分担をどうするかだと思います。UI周り、ロジック、バックエンド処理(DB周り)、あるいは外部API呼び出しなどの開発役割分担をどうするか？　WEBアプリケーションの場合は、JavaScript にUIとロジックを任せる場合が多くあります。そうすると、一人のエンジニアに負担がしわ寄せされてしまうということも多く見られると思います。

そこで、チームの負担のばらつきを軽減するために、メッセージ通信で、UI、ロジック実行などをプロセス祖結合させます。具体的なイメージは以下の図のようになります。

![hackathon-architecture-2.png](https://qiita-image-store.s3.amazonaws.com/0/74673/2a783bcc-9bb6-85e1-df34-d98532933662.png "ハッカソンアーキテクチャ")

このアーキテクチャですとチームの分担は以下のようになります。

- UI を担当する人 １名
- モバイルアプリケーションを担当する人 １名
- Node-RED でロジックを実装する人 １名
- DB 設計担当者 １名
- 外部APIの調査、呼び出し検証とメソッド特定をする人 １名

５名未満のチームの場合は、WEBかモバイルだけにしたり、バックエンドシステム担当を１名に統合するなどで工夫する必要があるでしょう。DBはハッカソンではいらないかもしれません。

Node-RED で祖結合を実装するには、３つほどテクニックがあります。

1. websocket を利用する方法
2. メッセージ通信を利用する方法
3. Node-RED を REST API提供するサーバーにする方法


###1.websocket を利用する

おそらく一番単純な方法だと思われます。WEBクライアント側ではHTML5をサポートしたブラウザであればサポートされます。

####クライアント実装について

たとえば、フォームがありフォームのデータ POST する処理が必要とします。この場合、 Node-RED に送りたい場合は次のようなコードになるかと思います。

	// Webクライアント側での JavaScriptサンプル
	var ws;
	var server = window.location.hostname;
	var port = window.location.port;
	var wsUri = 'ws://'+server+':port/ws/socket'
	ws = new WebSocket(wsUri);
	
	ws.onmessage = function (evt) {
		// イベント処理をここに入れる
		// おおくは HTML の加工処理
	｝
	
	$('form').submit(function() {
		var val = $('<ｈｔｍｌファイルのタグ>').val();
		ws.send(val);
	}

JavaScriptでは、WebSocket のクライアントを作成します。formからのpostを受けて、ws.send() でデータを送ります。データの形式は任意ですが、あまり長いのはサポートされていません。またクライアントからは、通信を ws.onmessage() で待っています。Node-RED の処理結果を受けて、html のレンダリングを実施するという処理を加えるのがよいでしょう。

#### Node-RED 側のフロー

Node-REDのフローは websocket の in/out をペアで配置します。

![websocket.png](https://qiita-image-store.s3.amazonaws.com/0/74673/7ccb9dee-58bd-4fb3-8fa9-40a7d859ed0b.png "websocketフロー")

このサンプルは単純ですが、実際には websocket in/out の間に様々なデータ加工処理が含まれるでしょう。たとえば、DBに永続化したり読み込んだり、あるいは外部REST API の呼び出しなどが含まれると思います。

websocket out には以下の変数を渡してあげます(msg. プレフィックスは省略)。

| 変数 | 説明 |
| :----------- |-------------|
| payload     | websocket を使ったメッセージ。任意の形式をサポート |
|_session     | この値をクリアするとすべてのクライアントにブロードキャストする |

websocket in/out をペアで使うと、msg._session 値をクリアしない限り、メッセージを送信したクライアントにのみ、websocket で通信を行います。内部でセッションを管理しているようです。



### 2. メッセージ通信を利用する

昨今、小型デバイスを使ったIoT (Internet of Things)アプリケーションもハッカソンでも開発されるようになっています。IoTアプリケーションも含め、メッセージ通信でフロントエンドとNode-REDの処理を分ける方法です。

MQTTプロトコルやAMQP (Advanced Message Queuing Protocol) はさまざまなサンプルがあるので、ここでの実装例は割愛しますが、注意点としてはそれらのプロトコルを処理するブローカーが必要ということです。MQTT の場合は、Eclipse IoT ( http://iot.eclipse.org )　や、IBM の IoT Foundationサービス（https://internetofthings.ibmcloud.com/) 、もしくは最近出てきた Amazon IoT サービス( https://aws.amazon.com/iot/ ) を利用するとよいでしょう。

AMQPは、RabbitMQ (Pivotal社)、WebSphereMQ/MQLight(IBM社)などが有名ですが、それぞれクラウドサービスがあります。

ブローカーが必要なため、websocket に比べるとプロトコルスキルセットがあることが前提となるので、少し難易度があがります。

####Node-RED での実装

Node-RED側のフローはたとえば次の図のようになるかと思います。

![mqtt-amqp.png](https://qiita-image-store.s3.amazonaws.com/0/74673/2534097f-cb3e-8841-7dbc-cabbeab5fc45.png "MQTT AMQP 処理フロー")

上段は、 MQTT で、下段は mqlight です。AMQP Node-RED node ( node-red-amqp )もあるようですが、どうやら完成度が低そうなので、mqlight を使うのがよいかと思います。どちらにしても、websocket と似てますね。




###3. Node-RED を REST API提供するサーバーにする

####Node-RED側での実装

Node-RED では "http　in" と　"http respose" node を使います。必ずペアで利用するのがコツです。

![http-restapi.png](https://qiita-image-store.s3.amazonaws.com/0/74673/efe9c2c2-f9d4-e7df-4585-f3ac14750baa.png "REST API実装")

例では、ひとつの function node ですが、http in/http response の間にロジックを実装します。http response には次の設定を実装する必要があります (msg. prefix は省略）。

| 変数        |説明      |
| ----------- |-------------|
| payload | response の body |
| statusCode| response の status code デフォルトは 200 |
| headers | response の header. field/value ペアの JSON形式で記述 |


サンプルでは、msg.payload に "Hello, Node-RED!" を設定しています。以下はフローです。

```
[{"id":"cdfd50b0.58bc7","type":"http in","name":"","url":"/sayhello","method":"get","swaggerDoc":"","x":90,"y":157,"z":"b861add6.51b118","wires":[["b47bad02.8b4ae8"]]},{"id":"b47bad02.8b4ae8","type":"function","name":"Say Hello!","func":"msg.payload = 'Hello, Node-RED !';\nreturn msg;","outputs":1,"noerr":0,"x":292,"y":157,"z":"b861add6.51b118","wires":[["a6c7e732.bcae1"]]},{"id":"a6c7e732.bcae1","type":"http response","name":"","x":489,"y":157,"z":"b861add6.51b118","wires":[]}]
```

実際にこの REST api を呼び出してみます。Node-RED はローカルで実行しています。

```
$ curl http://localhost:1880/sayhello
Hello, Node-RED !
```
"Hello, Node-RED !" と出てますね。より実用的な実装例が今回の Node-RED Advent Calendar [1分で実装！Node-REDでREST API呼び出し] (http://qiita.com/zuhito/items/ed5f505edaac2baeadd9) にありますのでぜひご参照を！


####クライアント側での利用形態

クライアント側では REST API を呼び出すロジックを実装します。注意点としては CORS(Cross-Origin Resource Sharing)になる可能性があるので、ドメインを超えた API呼び出しのスキルが必要です。WEB UI の場合、ハッカソンであれば、JSONP という抜け道を利用するという手もありますが、CORS 実装スキルが必要な点で少し難があります。しかし、REST API 呼び出しに慣れている開発者は多いと思われるので、REST API 型結合で実装というのが websocket 結合よりも早いかもしれませんし、より実用的だと思われます。



##まとめ

今回の記事では、コラム風に Node-RED との個人的な使い始めのきっかけと、個人的なハッカソンでの利用シナリオを盛り込みました。Node-RED を使い始めたきっかけは皆さんさまざまだと思いますが、おそらく今後も深く付き合い続ける存在となるでしょう。それほど、魅力があるソフトウェアです！　またハッカソンに参加する機会があれば、Node-RED を大いに活用しましょう。