Azure Functions を使ってみよう 〜 クイックスタートしてみよう 〜

どうもです。まーやです。
今日は気になっていた [Azure Functions](https://azure.microsoft.com/ja-jp/services/functions/) についての概要と、クイックスタートという機能(?)を使ったHello World的なシステムを1つ作ってみたいと思います。

# Agenda
- Azure Functionsとは
- クイックスタートを使ってFunctionsデビュー
- まとめ

# Azure Functions とは
ここ最近ブームしている(ような気がする)イベント駆動型のサーバレスシステムという分類に当たるサービスです。
AWSを知っている＆いじったことある人に分かりやすくいうと、[AWS Lambda](https://aws.amazon.com/jp/lambda/)のAzure版だと思ってもらえれば概ねOKです。類似サービスとは言えど、当然若干できることに違いがありますので、そんなところも気をつけつつ、概要を見ていきたいと思います。

### 機能について
何かしらサービスを起動させたいイベントアクションがあった場合に、自分が書いたシステムが発動してくれます。Functionsでは大きく分けて3種類のイベント型を受け取ることができます。

①タイマー型
毎月・毎時・毎分・10秒おき、などなどCRONのように時間指定でタイマー稼働させたいシステムがある場合に利用できます。
e.g.)毎日13時に指定のファイルが到着しているか確認する etc.

②Microsoft別サービス連携型
Microsoft内の別サービスをイベントとして扱うことができます。①のタイマー型と異なり、時間に縛られず、データの動きや前処理サービスの終了とともに即時実行できます。基本はAzure内のサービスとの連携となりますが、例えばOneDriveとの連携なんかもできるんですよ。
e.g.)BLOBに新商品データが到着したら必要な情報だけ抜き出してDBに登録する etc.

③webhook型
AWS Lambdaでは他システムのwebhookを受け取りたい場合は[AWS API Gateway](https://aws.amazon.com/jp/api-gateway/)と連携させる必要がありますが、FuntionsはFunctionsだけで完結させることができます。これは地味に嬉しい強みではないかと個人的には思っています。
e.g.)[BackLog](http://www.backlog.jp/)でwikiが更新されたらSlackに通知する etc.

個人的にはOneDrive連携やwebhook連携が簡単にできるのはポイント高いなと思っています。

### 使い方
- 実行させたい処理を書く
- 発動させたいイベントの設定をダッシュボードから行う
- 書いた処理を登録する

だけで使えるようになります。イベントテンプレートが複数用意されていますので、テンプレートを利用して登録すると簡単です。ただ、ざっと見た感じ今のところ(*1)イベントテンプレート数はAWS Lambdaの方が多いかなぁ。Functionsは割と新しいサービスなので、これからどんどん増えるでしょう(期待してます)。

また、クイックスタート機能というものがあり、タイマー型などのイベント種別(シナリオ)と利用言語の選択を行うとサンプルコード＆オンラインエディタ(ダッシュボード上のコード作成エディタとFunctions専用ダッシュボード)の利用説明をしてくれます。初めてでまず何をしたらいいかわからない！という方はここでオンラインエディタの使い方をよく読んでから作業を開始してみるといいと思います。
ただし、このクイックスタートに対応している言語はC#とJavaScript(Node.js)のみです(*1)。その他言語を利用したい方は新規作成からスタートしましょう。

### 利用できる言語
現在Functionsで利用できる言語は以下の通りです。

- C#
- F#
- JavaScript(と書いてあるが事実上Node.js)
- Python(2系/3系)
- PHP
- Bash

Javaも使えるようにならないかなぁ・・・なるといいなぁ・・・
Pythonは2系3系両方選べます

## 料金について
料金は「サーバを動かしている間だけ」課金されます。
つまり、1秒で処理が完了した場合は、1秒分だけお支払いです。一日10分しか動かないバッチのためにサーバを1台立てるとか、クラウドサービスを使ってサーバを立てたけど1時間が最低課金単位なので1時間分の料金が取られる、なんていう無駄なコストを極限まで抑えることができるわけです。

では料金はどのように計算するのか。料金の計算には次の2軸を利用します(*1)。

- 実行時間×処理で利用したGB数
    - 1GBあたり1秒0.001632円
    - 400,000GB秒 までは無料で使えます
- 実行回数
    - 100万回毎に20.40円
        - 100万1回で40.80円
    - １００万回までは無料で使えます

つまり、個人でちょっと使ったり、毎時処理をちょっと行うくらいだったら無料で使えるということですね。ありがたや。webhook型の処理をちょっとやりたいだけならAWS LambdaよりFunctionsの方がお安く実行できるわけです(*2)。

# クイックスタートを使ってFunctionsデビュー
では早速クイックスタート(Node.js)を使ってFunctionsデビューして見ましょう。GETリクエストをFunctionsに投げると「Hello![あなたの名前]」と返してくれるAPIを作って見ましょう。

①ダッシュボードの新規作成ボタンからComputeを選択し、「Function App」を選択します。あれ？FunctionsなのにFunction Appなの？と思った方。私も思いました。が、とりあえず気にせず進みましょう。Function.*な名前を持ったシステムは他にありません。
![スクリーンショット 2016-12-11 15.10.20.png](https://qiita-image-store.s3.amazonaws.com/0/60850/44d9ccc3-b247-893a-4abc-d3b606b59a15.png)

②名前などを付与して、サクッと作成ボタンを押しましょう。3分〜5分くらい待っていると使えるようになります。
![スクリーンショット 2016-12-11 15.15.42.png](https://qiita-image-store.s3.amazonaws.com/0/60850/af50ad07-42da-d6c4-1acb-8d1b107f5eb2.png)

③出来上がったFunctionsをクリックし、左下にあるクイックスタートボタンをクリックしましょう。簡単設定モードになります。今回は次の設定で進めます。
![スクリーンショット 2016-12-11 15.18.55.png](https://qiita-image-store.s3.amazonaws.com/0/60850/a85440f7-4c90-3001-0c41-fa4082e113f1.png)


- webhook + API
- JavaScript

選択したら「この関数を選択する」ボタンをクリックします。

④関数のサンプルが作成されると、このFunctionsダッシュボードの使い方ツアーが開始されます。ツアーで使い方について教えてくれるので、ここではFunctionsダッシュボードの使い方については割愛します。ツアーに出てくる文章をよく読んでね！

⑤今出来上がっているコードは、nameが存在すれば200とnameを返却する、という簡単なシステムです。HTTPメソッドはGETでもPOSTでもなんでもOKな設定になっています。試しにテスト実行して見ましょう。
右上のテストボタンをクリックすると、テストリクエストを送ることができます。
![スクリーンショット 2016-12-11 15.44.38.png](https://qiita-image-store.s3.amazonaws.com/0/60850/d00d4c2e-212b-a077-d63a-48331564e1ca.png)
画面右側に出現したテストリクエスト設定ボックス内を変更することで様々なリクエストを投げることができます。とりあえず設定を変えずに「実行」ボタンをクリックして見ましょう。テストリクエスト設定ボックスの下の方にリクエスト実行結果が返ってきているはずです。

テスト、と言っていますが、実際は「関数のURL」というこのFunctionに当てられたURLを叩くツールを用意してくれているだけです。関数のURLに「&name=[あなたの名前]」を追加してブラウザから叩いてみると、同じ結果がxmlで返却されます。

⑤リクエストをGETのみに限定して見ましょう。リクエスト・レスポンスの設定をするために「統合」メニューを開きます。
![スクリーンショット 2016-12-11 15.58.11.png](https://qiita-image-store.s3.amazonaws.com/0/60850/a4421ae8-badc-55f1-eded-929103d343da.png)
統合メニュー内「HTTP trigger」で設定を行います。「許可されているHTTPメソッド」が「All methods」になっていますので、これを「Selected methods」に変更します。右下にHTTPメソッド一覧が出てきますので、GETのみチェックが入っている状態にして、保存します。

⑥開発メニューに戻り、テストページを開きなおすと、GETしか設定できないようになります。手元でPOSTリクエストを打ってもリクエストエラーになるようになりました。

### メソッド(function)分けについて
一定の条件を満たしていれば、functionメソッドの切り出しや、jsファイルの分割化も可能です。

- エントリーポイントが書かれているjsファイル名がindexもしくはrunであること

新しくファイルを追加したい場合などは開発メニューの「ファイルの表示」から追加することができます(テストボタンの隣です)。

なのでこんなコードでも大丈夫です。もちろん↓のmakeStr functionを別のJSファイルにすることも可能です。

```
module.exports = function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    if (req.query.name || (req.body && req.body.name)) {
        str = makeStr("Hello " , (req.query.name || req.body.name));
        res = {
            // status: 200, /* Defaults to 200 */
            body: str
        };
    }
    else {
        res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
    context.done(null, res);
};

function makeStr(strA, strB) {
    return strA + strB;
}
```

# まとめ
本当にちょっとした処理をぺいっと書きたい場合は重宝しそうです。料金的にも個人で使うに優しい感じで良いと思います。ただ、私はNode.jsチカラが低いですし、C#なんて書いたこともない食わず嫌い感があるので、Pythonで使い勝手がどうか、次回試して見たいと思います。Javaは是非対応してほしいな。

以上です。




------------------------
*1 : 2016/12/11 現在
*2 : webhook型の場合, AWS LambdaはAPI Gatewayと併用する必要があります。LambdaはFunctions同様に料金自体微々たるもの＆無料枠ありのためほとんど料金差異はありませんが、API Gatewayについては最低3.5ドル+データ転送料金がかかります。どちらにせよ数百円程度なのですが、一応・・・。([Lambda料金表](https://aws.amazon.com/jp/lambda/pricing/) /[API Gateway料金表](https://aws.amazon.com/jp/api-gateway/pricing/))