Webhook as a ServiceでIoTのserverlessなバックエンド考える - Part 2: Webtask.ioのHello world

## このシリーズ

* [Webhook as a ServiceでIoTのserverlessなバックエンド考える - Part 1: リソース](http://qiita.com/masato/items/ecc786a9703c314844e3)
* [Webhook as a ServiceでIoTのserverlessなバックエンド考える - Part 2: Webtask.ioのHello world](http://qiita.com/masato/items/5689238a4d90cfd8a307)

## Webtask.io

　[Webtask.io](https://webtask.io/)を使うとserverlessにNode.jsで書いたスニペットコードをMicroServiceとして簡単に公開することができます。

　Webtaskの仕組みはIdentity-Management-as-a-Service (IdMaaS)として有名な[Auth0](https://auth0.com/)のバックエンドとして採用されているようです。[CoreOS](https://coreos.com/), [Docker](https://www.docker.com/), [etcd](https://github.com/coreos/etcd), [fleet](https://github.com/coreos/fleet)のアーキテクチャの上で動いています。マルチテナントなMicroServicesのためのプラットフォームとしてとても参考になります。

参考

* [If This Then Node.js](https://auth0.com/blog/2015/07/28/if-this-then-node-dot-js-extending-ifttt-with-webtask-dot-io/)
* [Rethinking backend with webtasks](http://tomasz.janczuk.org/2015/04/rethinking-backend-with-webtasks.html)

## Webtask CLI

　Webtask.ioのインタフェースは[Webtask CLI](https://webtask.io/cli)を使います。npmのパッケージとして[wt-cli](https://www.npmjs.com/package/wt-cli)公開されています。CLIはグローバルにインストールすると`wt`コマンドが使えるようになります。

```bash
$ sudo npm install wt-cli -g
```

　メールアドレスか携帯の番号を入力して`wt`コマンドの初期設定をします。指定したメールアドレスにVerification codeが届きます。

```bash
$ wt init xxx@gmail.com
Please enter the verification code we sent to xxx@gmail.com below.
Verification code:
```

　メールで届いたコードを入力すると`wt`コマンドの初期処理が終了します。

```bash
Welcome to webtasks! Create your first one as follows:
```

　`wt`コマンドで使う認証情報は`~/.webtask`に記述されています。アカウントごとに専用のコンテナが作成されるようです。

```json:~/.webtask
{
  "default": {
    "url": "https://webtask.it.auth0.com",
    "container": "{アカウントのコンテナ名}",
    "token": "{アカウントのwebtask token}"
  }
}
```

参考

* [Sandboxing Code in the Era of Containers](https://medium.com/aws-activate-startup-blog/sandboxing-code-in-the-era-of-containers-294edb3a674#.fl2mobcbl)

## webtaskを作成して実行する

　[Webtask CLI](https://webtask.io/cli)のページではアカウントを作成してwebtaskを実行するまで30秒でできると書いてあります。実際には慣れないともう少し時間がかかりますが簡単にMicroServiceを作成して実行できます。

　webtaskをNode.jsの関数として作成します`wt init`コマンドの最後に作成方法も表示されるのでそのままコピーして実行します。`wt create`コマンドには

```bash
$ echo "module.exports = function (cb) { cb(null, 'Hello'); }" > hello.js
$ wt create hello.js
```

　こちらもCLIのコマンドを実行すると次の動作を教えてくれます。

```bash
Run your new webtask like so:
$ curl https://webtask.it.auth0.com/api/run/{アカウントのコンテナ名}/hello?webtask_no_cache=1
```

　curlコマンドから作成したwebtaskのURLを実行すると"Hello"とレスポンスがあります。デフォルトではどの環境からもこのURLを実行することができます。

```bash
"Hello"
```


## Webtask tokenにコードのurlを組み込んで実行する

　webtask clusterのAPIを実行する場合は、必ずHTTPヘッダの`Authorization: Bearer`またはクエリ文字列に`key={webtask token}`として[webtask token](https://webtask.io/docs/token)の指定が必要です。`wt`コマンドはデフォルトで`~/.webtask`の`default`プロファイルの`token`フィールドを使います。


### url

　webtask tokenは[JWT (JSON Web Token)](https://jwt.io/)のクレームとして権限や制約を定義します。セキュアな情報をトークン化して使うことができます。

　`url`プロパティは特定のURLで指定されたwebtask codeのみ実行可能なwebtask tokenを発行するときに使います。webtask clusterはこのURLからwebtask codeをHTTP GETして実行します。この新しいwebtask tokenを使うアプリやユーザーに対して制限をかけることができます。

 新しいwebtask tokenは以下のエンドポイントにHTTP POSTして発行します。

```
HTTPS POST /api/tokens/issue
Content-Type: application/json        
```

　curlコマンドからリクエストの認証用にwebtask token (A1)を使い、webtask codeの実行に制限をかけた新しいwebtask token (A2)を発行します。発行したwebtask tokenは`RESTRICTED_TOKEN`環境変数に保存します。

```bash
export RESTRICTED_TOKEN=$(curl -s https://webtask.it.auth0.com/api/tokens/issue -H "Authorization: Bearer $RESTRICTED_TOKEN" -H "Content-Type: application/json" --data-binary '{"url":"http://bit.ly/18L4CmA"}')
```

　リクエストはJSONで形式です。`url`プロパティの`http://bit.ly/18L4CmA`は、[WT3.js](https://gist.githubusercontent.com/tjanczuk/d2357e7860d9103cec16/raw/874ca9dd465f10198f89328e181dba0333d9abdf/WT3.js)に展開されます。発行した新しいwebtask tokenの`RESTRICTED_TOKEN`の権限は、以下のwebtask codeの実行だけに制限されます。

```js:WT3.js
return function (context, cb) {
    cb(null, "Hello, " + context.data.name);
}
```

　すでに必要な情報はwebtask tokenに組み込まれているので`RESTRICTED_TOKEN`を使う場合はownerの情報や実行するwebtask codeの指定は不要です。

```bash
$ echo $RESTRICTED_TOKEN
eyJhxxx
```

　curlコマンドに認証情報としてRESTRICTED_TOKENをクエリ文字列の`key={webtask token}`に追加します。

```bash
$ curl -X POST \
  "https://webtask.it.auth0.com/api/run/{アカウントのコンテナ名}?name=Masato&key=eyJhxxx" 
```

　以下のレスポンスが返ります。

```bash
"Hello, Masato"
```


参考


* [HTTP API: Authentication](https://webtask.io/docs/api_auth)
* [HTTP API: Creating Webtask Tokens](https://webtask.io/docs/api_issue)
* [Issuing tokens from webtask code](https://webtask.io/docs/model_issue)
* [Fixing Webtask Code](https://webtask.io/docs/issue_fixed_code)