Saqib
Saqib

Reputation: 7412

Azure Functions: serving content for root URL

I have an C# Azure Function project, with a variety of functions.

One of the functions is to serve some HTML content. This function can currently be accessed at /api/home. However, I want to have it triggered for the root / URL.

I have added a proxies.json file in my project:

{
  "Home": {
    "matchCondition": {
      "methods": ["GET"],
      "route": "/"
    },
    "backendUri": "https://localhost:7071/api/home"
  }
}

But this still has no effect - it continues to serve up the default Azure Fucntions webpage.

Is there any way to do this?

Upvotes: 12

Views: 6014

Answers (4)

bredd
bredd

Reputation: 491

A Better Solution for Azure Functions V4.

tl;dr It turns out you can set a function route to "/". You just need the right settings.

As others have noted, proxies were disabled in v4. And then added back but they are still deprecated. Microsoft recommends using Azure API Management but that's way too complicated for just this use case.

This solution, which is backward compatible with V3, I got from an excellent blog post by Julian Hüppauff.

First, (this was the missing piece for me) you have to turn off the default Azure Functions homepage. You do this in your application settings. You must set AzureWebJobsDisableHomepage to true. On the Azure host you do this in Azure Functions Application Settings.

On your local machine, for testing, you add the setting to local.settings.json like this.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsDisableHomepage": "true"
  }
}

Next, as @Gangula mentioned, you turn off the default "/api" prefix to your functions. Add routePrefix to your host.json as follows:

{
  "version": "2.0",
  "extensions": {
    "http": {
      "routePrefix": ""
    }
  }
}

Finally, create your function and set a Route that will match the bare URL.

Edit: May 2024 Originally, I wrote that you set the Route on your function to "/". That quit working somewhere between .NET 6 and .NET 8. Setting route to that value seems to hang the runtime.

Instead set your Route to "{ignored:maxlength(0)?}" and add a string ignored argument to your function like this:

[Function("RootFunction")]
public IActionResult Run(
  [HttpTrigger(AuthorizationLevel.Anonymous, "get",
  Route = "{ignored:maxlength(0)?}")] HttpRequest req,
  string ignored = "")
{
}

In the comments, 0xced suggests setting Route to "{*ignored}". That will also work. However, doing so will make your function match any URL path so your root function becomes the default when no other path is matched. That may be what you want. But if you only want to match the bare domain name with no path then use "{ignored:maxlength(0)?}".

Thanks to 0xced because they clued me into the solution I'm using.

I hope this helps people coming to this problem post V4!

Upvotes: 15

Gangula
Gangula

Reputation: 7294

EDIT Feb 12, 2024

Looks like below mentioned approach is not valid - especially since proxies are deprecated since Functions v4.

Checkout @bredd's answer here for a better approach which is backward compatible.


Jun 07, 2021

You can add a Proxy in the proxies.json file to a selected function and re-direct it to the root url like below

{
  "$schema": "http://json.schemastore.org/proxies",
  "proxies": {
    "Proxy1": {
      "matchCondition": {
        "route": "/"
      },
      "backendUri": "https://<AnotherApp>.azurewebsites.net/api/<FunctionName>"
    }
  }
}

This will redirect all the calls to the rool URL to the function with name "<FunctionName>"


Bonus Tip:

If you'd like to remove /api from your URL, you can do so by adding the following code in host.json file

  "extensions": {
     "http": { 
       "routePrefix": "" 
       } 
    }

Upvotes: 4

Oliver Bock
Oliver Bock

Reputation: 5095

I don't know about matchConditions but setting route to / works for me in v4 Functions (Node):

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "route": "/",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

Upvotes: 0

Frank Borzage
Frank Borzage

Reputation: 6796

I'm afraid you can't use the root path to access this function, because https://localhost:7071/ is always the default page of Azure function:

enter image description here

Below are my verification steps, I will change the path of the function to https://localhost:7071/, but it still displays the default page of Azure function app.

By default, the route for your azure function would be localhost:7071/api/{functionName}

You must have noticed by now that almost all the function routes had /api/ in the route. In case, you wanted to change it, you can change it by modifying the content using the host.json.

You need to add "extensions": { "http": { "routePrefix": "" } } in your host.json:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensions": { "http": { "routePrefix": "" } }
}

Now, your route might look like this:

localhost:7071/{functionName}

You also need to set the Route in the code to "".

[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "")] HttpRequest req,

enter image description here

The current route should meet your requirements:

enter image description here

But using this path to access this function still fails, so I think it is invalid to set the path of the Azure function as the root path, and you cannot use it to access your Azure function.

If you deploy to Azure portal, you can try to add "AzureWebJobsDisableHomepage ": true in app settings to disable the homepage of Azure function. I tested it locally and it doesn't seem to work. Azure portal seems to work.

Upvotes: 4

Related Questions