1

I spent a lot of time, but I did not find any javascript example or document about how can I set a path parameter of a blob path from Azure function. How can I set the {filename} of "path": "randomnum-container/{filename}", from the function inside?

function.json

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "blob",
      "name": "outputBlob",
      "path": "randomnum-container/{filename}",
      "connection": "randomnum_STORAGE",
      "direction": "out"
    }
  ],
  "disabled": false
}

index.js

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    const max = 100;
    const num = Math.floor(Math.random() * Math.floor(max));
    // how to set outputBlob {filename} parameter?
    // let's say I want to save every request to {num}.txt
    context.res = {
        status: 200,
        body: {
            "number": num
        }
    }
};

2 Answers 2

3

Cause the nodejs function doesn't support to bind the container, so if you want to bind the dynamic blob, you have to define it before the function running.

And you are using the HTTP trigger function, so you could define the blob name in the request. The below is my function.

My function.json:

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },{
      "name": "outputblob",
      "type": "blob",
      "path": "outputcontainer/{outblobname}",
      "connection": "AzureWebJobsStorage",
      "direction": "out"
    }
  ]
}

index.js:

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

    context.bindings.outputblob = "test string";
    context.done();


    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"
        };
    }
};

Then in the postman, I send the below json data, send the request, the function will bind the blob with 001.txt.

{
"outblobname":"001.txt"
}
Sign up to request clarification or add additional context in comments.

Comments

1

Thanks George!

I found this solution and another one. The drawback of this solution, I can not manipulate the file name in the serverless function. The other soultion I've made is a durable function.

sendMessage.js (starter)

const df = require("durable-functions");

module.exports = async function (context, req) {
    const client = df.getClient(context);
    const instanceId = await client.startNew(req.params.functionName, undefined, req.body);

    context.log(`Started orchestration with ID = '${instanceId}'.`);

    return client.createCheckStatusResponse(context.bindingData.req, instanceId);
};

function.json (sendMessage.js)

{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "route": "orchestrators/{functionName}",
      "methods": [
        "post",
        "get"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "name": "starter",
      "type": "orchestrationClient",
      "direction": "in"
    }
  ]
}

messageOrchestrator.js

const df = require("durable-functions");

module.exports = df.orchestrator(function* (context) {
    const outputs = [];
    const input = context.df.getInput();
    input['filename'] = `file_${input['name']}.txt`;

    outputs.push(yield context.df.callActivity("logMessage", input));


    return outputs;
});

function.json (messageOrchestrator.js)

{
  "bindings": [
    {
      "name": "context",
      "type": "orchestrationTrigger",
      "direction": "in"
    }
  ]
}

logMessage.js (activity)

module.exports = async function (context) {
  context.bindings.filestore = context.bindings.payload;
  return `Hello ${context.bindings.payload}!`;
};

function.json (logMessage.js)

{
  "bindings": [
    {
      "name": "payload",
      "type": "activityTrigger",
      "direction": "in"
    },
    {
      "name": "filestore",
      "type": "blob",
      "path": "{messagetype}/{filename}",
      "direction": "out",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

The important things are in the messageOrchestrator and in the logMessage.js's function.json. I manipulate filename in the orchestrator and binding the payload's attribute in the activity's function.json.

This worked well for me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.