LoginSignup
8
3

More than 5 years have passed since last update.

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

Posted at

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

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

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

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

{
  "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 パラメータを追加したら派手なエラーになった。

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 では、パラメータは、contextinput しか不可の様子。

どないするねん、、、

解決策

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

function.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
}

そんで、コードはこんな感じ。テンプレートにちょっと足しただけ。

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が対応している。

Screen Shot 2017-10-07 at 4.53.10 PM.png

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

Screen Shot 2017-10-07 at 4.54.05 PM.png

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3