16

I know that I can use url parameters like this:

"myfunction?p=one&p2=two"

and in code that becomes

request.query.p = "one";

but I would prefer to get it like this (express routing style):

"myfunction/:myvalue"

and use this url:

/myfunction/nine

which becomes this in code:

request.params.myvalue = "nine"

but I can't seem to find how to configure a route path like that in Azure Functions, any ideas or docs?

Yves M.
  • 29,855
  • 23
  • 108
  • 144
contractorwolf
  • 438
  • 1
  • 3
  • 14

2 Answers2

29

We've shipped route support for HTTP Triggers in Azure Functions. You can now add a route property which follows ASP.NET Web API route naming syntax. (You can set it directly via the Function.json or via the portal UX)

"route": "node/products/{category:alpha}/{id:guid}"

Function.json:

{
    "bindings": [
        {
            "type": "httpTrigger",
            "name": "req",
            "direction": "in",
            "methods": [ "post", "put" ],
            "route": "node/products/{category:alpha}/{id:guid}"
        },
        {
            "type": "http",
            "name": "$return",
            "direction": "out"
        },
        {
            "type": "blob",
            "name": "product",
            "direction": "out",
            "path": "samples-output/{category}/{id}"
        }
    ]
}

.NET sample:

public static Task<HttpResponseMessage> Run(HttpRequestMessage request, string category, int? id, 
                                                TraceWriter log)
{
    if (id == null)
       return  req.CreateResponse(HttpStatusCode.OK, $"All {category} items were requested.");
    else
       return  req.CreateResponse(HttpStatusCode.OK, $"{category} item with id = {id} has been requested.");
}

NodeJS sample:

module.exports = function (context, req) {

    var category = context.bindingData.category;
    var id = context.bindingData.id;

    if (!id) {
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: "All " + category + " items were requested."
        };
    }
    else {
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: category + " item with id = " + id + " was requested."
        };
    }

    context.done();
}

Official docs: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook#url-to-trigger-the-function


Today, you'd have to use a service like Azure API Management to customize your routes.

There is a PR in progress to add custom routes to Azure Functions itself. The team is hoping it will land in the next release. https://github.com/Azure/azure-webjobs-sdk-script/pull/490


Note: I'm a PM on the Azure Functions team

Chris Anderson
  • 8,305
  • 2
  • 29
  • 37
  • is there a way to change the "function name" from the default ones? so I want to create a url that represents a restful service/api and then provide a swagger definition. So each function handles a separate resource. Coupled with the fact that there is no custom routing plus no way to change functionname (I am assuming), there is no way to create Restful api based on Azure functions? – Farax Sep 11 '16 at 06:00
  • You can set the name when you create a Function. You can also change the Function name if you change the folder name on disk. You can do that via Kudu (on the Function App Settings menu). – Chris Anderson Sep 13 '16 at 06:56
  • 1
    This shipped! https://github.com/Azure/azure-webjobs-sdk-script/blob/dev/sample/HttpTrigger-CustomRoute-Post/function.json#L8 – Chris Anderson Nov 22 '16 at 17:26
  • @ChrisAnderson-MSFT in the route you specified `guid` but in the function you are expecting `int?` . is that a typo? does azure functions routing support `guid` attribute. I am getting some error ., SO Link https://stackoverflow.com/questions/46743180/is-attribute-routing-possible-in-azure-functions – Venkata Dorisala Oct 14 '17 at 10:00
  • for node.js - wish you would just stick with what the node community is used to - express like routing. this context wrapping of the req/res objects makes things less familiar and more difficult to use all the available middlewares – Michael Feb 07 '18 at 07:30
  • Yeah, I agree. We didn't do it in the initial release, so it was hard to add it in a non-breaking way in v1. Haven't made any advances yet in v2, but I think we'll move in that direction or at least support everything to make it possible via frameworks like azure-functions-express (which is pretty good, but has had to hack around us. – Chris Anderson Feb 11 '18 at 04:31
8

azure-function-express

With azure-function-express you can use all expressjs functionalities including routing ;)

const createHandler = require("azure-function-express").createAzureFunctionHandler;
const express = require("express");

// Create express app as usual
const app = express();
app.get("/api/:foo/:bar", (req, res) => {
  res.json({
    foo  : req.params.foo,
    bar  : req.params.bar
  });
});

// Binds the express app to an Azure Function handler
module.exports = createHandler(app);

See more examples here including a way to handle all routes within a single Azure Function handler.

PS: Feel free to contribute to the project!

Yves M.
  • 29,855
  • 23
  • 108
  • 144