6

So I'm aware of these two questions that seem to be asking the same thing:

How to remove the word ‘api’ from Azure functions url

How to change the base "/api" path on Azure Functions (v2)?

However, I can still not get rid of the "api" prefix in my route.

My host.json looks like:

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

And on my HttpTrigger I'm setting my custom route:

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "myapp")] HttpRequest request,

However, when I run the app locally the end point is coming up as:

[POST] http://localhost:7071/api/myapp

If I change my host.json to:

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

My app is now running on:

[POST] http://localhost:7071/something/myapp

So it appears that giving an empty string "" is just not working. Any ideas? (I've done all the usual stuff: clean solution, delete bin/obj folder etc.)

FYI from my function app I'm using:

<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />

EDIT:

I'm also referencing these packages from the function app (though I don't see how this would cause this problem):

<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.1.1" />

EDIT 2

I've narrowed down the problem to this code that is called in Startup.cs:

IConfiguration configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>();

IConfiguration combinedConfig = new ConfigurationBuilder()
    .AddConfiguration(configuration)
    .AddAzureKeyVault(kvEndpoint, kvClient, new DefaultKeyVaultSecretManager());
    .Build();

builder.Services.AddSingleton(combinedConfig);
// <-- this line causes the prefix "" to revert to "/api"

It essentially is adding key vault as a configuration provider to the stack of providers all ready there. (Note it doesnt matter what .Add methods I call on configuration builder, its the registration that is causing a problem). Is there another way to write this maybe?

bytedev
  • 8,252
  • 4
  • 48
  • 56
  • do you have something like Startup class in your azure function? – Ivan Glasenberg Jun 18 '20 at 05:34
  • @IvanYang yes. I am using: `Microsoft.Azure.Functions.Extensions` package as well. Can this possibly be related?? :-) – bytedev Jun 18 '20 at 06:29
  • hi, can you please show us all the packages and a sample code? and are you using some DI by adding the `Startup.cs` in your project? This should work and we used it many times. – Ivan Glasenberg Jun 18 '20 at 06:34
  • Unfortunately that would be a lot of code and it might be too sensitive to post here. Yes I am using `Startup - Configure` to register dependencies and configuration and nothing else. Though I'm not sure how registering dependencies would stop me from using `""` for my route prefix when simply specifying `"something"` as the route prefix works. Any ideas? – bytedev Jun 18 '20 at 06:39
  • The dependencies I'm registering are agnostic to being used by a function app (i.e. they have nothing to do with function apps) – bytedev Jun 18 '20 at 06:40
  • Same code remove the `/api` on my side. I am not sure what happened, but maybe you can use `Proxies.json` to acheive 'remove' the `/api`? – Cindy Pau Jun 18 '20 at 06:48
  • @bytedev, if possible, could you please just show the code in Startup.cs? by the way, your new edit in your post seems wrong:). – Ivan Glasenberg Jun 18 '20 at 06:52
  • Why downvote this question? – Cindy Pau Jun 18 '20 at 06:58
  • @bytedev If `extensions.http.routePrefix = ""` is still not work, will you accecpt use proxy to 'remove' the `/api`? – Cindy Pau Jun 18 '20 at 07:01
  • @IvanYang damn your fast lol - hit refresh. I've narrowed down the problem. – bytedev Jun 18 '20 at 07:06
  • @bytedev Have you solved this problem? – Cindy Pau Jun 18 '20 at 07:10
  • @BowmanZhu nope, I can see the line causing problem however I dont currently know another way to write the code I put in EDIT 2. In fact I'm not sure if there is another way. I'm still confused why it would mess up only for empty string prefixes though. Very weird! – bytedev Jun 18 '20 at 07:13
  • 3
    @bytedev, try to add this line of code in the Startup.cs: `builder.Services.Configure(options => options.RoutePrefix = string.Empty);`. – Ivan Glasenberg Jun 18 '20 at 07:20
  • 1
    @IvanYang that does work. However, we are just overwriting whats in the host.json with that - thats later gonna confuse the hell out of someone :-). I'm going to research if there is a better way to add another config provider :-) – bytedev Jun 18 '20 at 07:28
  • @bytedev, another possible solution, you can use IOptions, see this [doc](https://medium.com/@aranmulholland/injecting-application-settings-into-azure-functions-using-ioptions-f9ca07ac80ce). – Ivan Glasenberg Jun 18 '20 at 07:34
  • @IvanYang thanks for your help. My answer/findings below. – bytedev Jun 18 '20 at 08:32

2 Answers2

7

So the mistake I seem to have made was very small. In the following code:

IConfiguration configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>();

IConfiguration combinedConfig = new ConfigurationBuilder()
    .AddConfiguration(configuration)
    .AddAzureKeyVault(kvEndpoint, kvClient, new DefaultKeyVaultSecretManager());
    .Build();

builder.Services.AddSingleton(combinedConfig);

ConfigurationBuild.Build() actually returns a IConfigurationRoot, NOT a IConfiguration (IConfigurationRoot is a superset of IConfiguration). So when registering it I was loosing something (probably config provider information).

Simply changing:

IConfiguration combinedConfig

to

IConfigurationRoot combinedConfig

fixes the problem (or you can use var, which I probably should have!).

Though this fixes the problem I am still a little confused why before changing the routePrefix in host.json to some non-empty string works but setting it to empty string does not. Would have thought simply having the setting in the host.json at all would just apply the value and not having it there would mean reverting to the default "api".

bytedev
  • 8,252
  • 4
  • 48
  • 56
  • Congratulations to solve this problem. You can mark your answer later, this will help others who meet the similar question.:) – Cindy Pau Jun 18 '20 at 08:37
-1

I tried, and it's working!

I used VS2019, Created Azure function default project with HTTP trigger and remove route prefix from host.json

enter image description here

Proj file

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <AzureFunctionsVersion>v2</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.31" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

After updating nuget packages with latest version, it's working.

enter image description here

Proj file

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <AzureFunctionsVersion>v2</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Core" Version="3.0.16" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.0.2" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>
Pankaj Rawat
  • 4,037
  • 6
  • 41
  • 73