Azure Functions の Node の Blob bindings でファイル名を指定する

Azure Functions の node で Storage Account のBindings を使って、ファイル名を指定しながら、ファイルを書いてみたい。ところが、マニュアルによると、動的なバインディングは、C# のみらしい。

* [Azure Functions triggers and bindings concepts: Configuring binding data at runtime](https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings)

# binding で名前指定ができるらしい。

ファイルアップロードするときに、ファイル名指定を当然したいだろう。どうやったら指定できるだろうか。ちなみに、私のケースでは、HttpTrigger でアップロードして、Storage Account の bindings に流すパターン。

* [Background image thumbnail processing with Azure Functions and NodeJS](http://stevenfollis.com/2016/09/24/background-image-processing-with-azure-functions-and-nodejs/)

これの定義を参照にしてみよう。

```json
{
  "bindings": [
    {
      "name": "myBlob",
      "type": "blobTrigger",
      "direction": "in",
      "path": "images-original/{name}",
      "connection": "thumbnailfunction_STORAGE",
      "dataType": "binary"
    },
    {
      "type": "blob",
      "name": "$return",
      "path": "images-thumbnail/{name}",
      "connection": "thumbnailfunction_STORAGE",
      "direction": "out"
    }
  ],
  "disabled": false
}
```

こんな感じで、`{name}` を指定できたらええやん。ちなみにC# だと、このname を最初に呼ばれるメソッドのパラメータに追加できたりするが、`node` だとそうは問屋が降ろさない。w パラメータを追加したら派手なエラーになった。

```js
module.exports = function (context, req, name) {

```
こんな感じにすると派手なエラーが

```
An unhandled exception occurred while processing the request.

InvalidOperationException: No value for named parameter 'name'.
Microsoft.Azure.WebJobs.Host.Bindings.Path.BindingTemplateToken+ExpressionToken.Evaluate(IReadOnlyDictionary<string, object> bindingData)

FunctionInvocationException: Exception while executing function: Functions.BindingTest
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

```

マニュアルを見ると、`node` では、パラメータは、`context` と `input` しか不可の様子。

* [Azure Functions JavaScript developer guide](https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-node)

どないするねん、、、

# 解決策

結論としては、下記の`{filename}` や `{extension}` はプログラムの中身から渡せない。orz 。しかし、インプットのバインディングから引き継ぐということなので、httpトリガーの URL から引き継ぐようにする。`Route` を指定してあげると良い。ちなみに、`function.json` は、ポータルだと、Function名 > Integrate > Advanced editor でみれる。

_function.json_ 

```json
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "route": "BindingTest/{filename}/{extension}",
      "name": "req"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "blob",
      "name": "outputBlob",
      "path": "outcontainer2/{filename}.{extension}",
      "connection": "carreviewstr_STORAGE",
      "direction": "out"
    }
  ],
  "disabled": false
}
```
そんで、コードはこんな感じ。テンプレートにちょっと足しただけ。

```js
module.exports = function (context, req) {

    context.bindings.outputBlob = "hello!";

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

# テスト実行

を、勝手に、GUIが対応している。

<img width="1021" alt="Screen Shot 2017-10-07 at 4.53.10 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/3470/1d6843d7-e6a6-387d-1acb-e90e5271f937.png">

できました。めでたしめでたし

<img width="685" alt="Screen Shot 2017-10-07 at 4.54.05 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/3470/9295571d-dc0d-772b-7f14-ad45f67c529c.png">