Reputation: 2773
I have created an Azure Function that receives an HTTP request and returns an HTTP request. The function:
I was able to get this to work when I placed the path to the blob in a query parameter, but it fails when that variable is in the route template.
I tried to make the route template: storage/{containerName:alpha}/{path:alpha} but it always returns a 404. Below is an example cURL of how the request is constructed.
GET /api/storage/example-container-name/example.jpg?code=SSBhbSBhIHRlYXBvdCwgZG8geW91IHRoaW5rIEkgd291bGQgcHV0IGEgcGFzc3dvcmQgaGVyZT8= HTTP/1.1
Host: hostdoesnotexist.azurewebsites.net
Cache-Control: no-cache
**Note:The host is not real, path and code are not real.*
I did find this question that was related to the Azure Functions Proxy doing the same thing, but this question is not applicable to the Functions.
Azure Functions Proxy - route to storage account
Using this Azure Functions HTTP and webhook bindings example, and scrolling to the Customizing the HTTP endpoint section, I created another function with the following code:
Function.json - id changed from int? to alpha
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get"
],
"route": "products/{category:alpha}/{id:alpha}",
"authLevel": "function"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
run.csx
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req,
string category,
string 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.");
}
So if the route is products/test/abcd then it responds with:
200 - "test item with id = abc has been requested."
But, if you change this to products/test/abcd.jpg then it responds with:
404 - The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
This is the same behavior I am seeing with the other function I created.
Does anyone know if this is a bug like the proxies example, or should my route look different? Again, I have this working using query parameters, but it fails when I move the variables into the route template.
Edited - Added files based on feedback function.json
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get"
],
"route": "products/{category:alpha}",
"authLevel": "function"
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
run.csx
using System.Net;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req,
string category,
TraceWriter log)
{
string id = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "id", true) == 0)
.Value;
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.");
}
proxies.json
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"GetJustArtinAroundStorageLinkProxy": {
"matchCondition": {
"route": "/products/{category:alpha}/{id}",
"methods": [
"GET"
]
},
"backendUri": "https://<company-name>.azurewebsites.net/api/products/{category:alpha}?id={id}"
}
}
}
Upvotes: 0
Views: 1870
Reputation: 12538
Currently, there is a limitation with the HttpTrigger and it does not support request with extensions (see this for details).
As stated in the issue, you can use proxies to workaround this limitation, but you do need to remove the alpha
constraint from your route.
Here's an example proxy configuration that will forward the id
you have above as a query string:
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Test": {
"matchCondition": {
"route": "products/{category}/{id}"
},
"backendUri": "https://<functionapp>.azurewebsites.net/api/<function>?id={id}"
}
}
}
You can adjust the above to match your requirements, but this should give you the behavior you're looking for.
Upvotes: 2