Just got started with azure functions. I am using it as an httptrigger for an IoT device.
I am trying to setup one function that will work for httptrigger requests coming from several IoT devices - So I dont have to setup one function per device. So ideally, in my c# file, I will have something like this:
DeviceClient deviceClient;
string iotHubUri = "myhub";
string deviceName = "something dynamic here that changes with device";
string deviceKey = "something dynamic here that changes with device";
Then , I'd like to get my function url to look something like this:
"https://<functionapp>.azurewebsites.net/api/<function>/{device_id}?code=xxxxx"
where device_id is the IoT device id.
I am not sure how to first setup the reference in the c# file to be dynamic and also how to get the url to look the way I intend.
Some help will be appreciated. Thanks
There is a route parameter is HTTP trigger exactly for this. Your trigger definition should look something like this:
"bindings": [
{
"type": "httpTrigger",
"route": "something/{deviceid}",
"name": "request",
// possibly other parameters
}
],
If you are using precompiled C# functions, you can do the same via attribute property, e.g.
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "something/{deviceid}")]
HttpRequest request,
string deviceid)
{
// do something based on device id
}
Customize your Azure function route
To customize your url you can use two files, the one in which is defined the function function.json and the host.json.
function.json suffix
in function.json you can define the base url adding to the bindings array the "route": "yourbaseurl" property. that should result in something like this
{
"scriptFile": "../dist/server.js",
"disabled": false,
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"route": "cool", ///// This is the line that you have to add /////
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
host.json prefix
On the host.jsonfile you can add a prefix to that route, let's say you want to add a fancy name group or so...
therefore your file should look something like this
{
"version": "2.0",
"extensions": {
"http": {
"routePrefix": "prefix" ///// here is that you include your prefix route /////
}
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
I just want one word or none
if you want to have just one word in your route leave the host.json "routePrefix": "" and the function.json "route": "therouteyouwant" or empty like "route": "".
Related
I am just starting to learn to implement Azure Functions with NodeJS and i am trying to add additional custom parameters to the trigger function
as this is the recommended way for input bindings by Microsoft, but I can't get it to work.
I am getting a 404 Not Found Error.
When I remove the id Object from the function.json, the function works, but the id is undefined.
I tried to call the function with get and id as query param and as post with the { id: 123 } in the body, but with no success.
Can anyone help out?
Thanks in advance.
index.ts
const httpTrigger: AzureFunction = async function (
context: Context,
req: HttpRequest,
id: string
): Promise<void> {
context.log("HTTP trigger function processed a request with id.", id);
context.res = {
body: {
id,
},
contentType: "application/json",
};
};
function.json
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "id",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
],
"scriptFile": "../dist/respository/index.js"
}
In Node js Azure function we don’t have an Attributes and Annotations so we cannot add additional parameters in azure functions. Attributes are not supported by JavaScript.
In Azure function C# class libraries and Java, the HttpTrigger attribute is available to configure the function.
You can set the authorization level and allowable HTTP methods in attribute constructor parameters, webhook type, and a route template. For more information about these settings, see configuration.
Refer here
I have azure functions written in nodejs. I can't find a way how to get data for example from my created azure cosmos db. I know that there is azure cosmos SDK, but i don't want to use that way.I want to learn to do it through the azure functions because it is possible with them also.
i try do to this:
function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "cosmosDB",
"name": "inputDocument",
"databaseName": "dbtodos",
"collectionName": "items",
"connectionStringSetting": "todos_DOCUMENTDB",
"partitionKey": "/all",
"direction": "in"
}
],
"disabled": false
}
index
module.exports = async function (context, req) {
context.res = {
// status: 200, /* Defaults to 200 */
body: context.bindings.inputDocument
};
};
after my deploy when i visit the automatically generated url - i can't even open the link.There is not requests coming back.
If i do some basic example where i don't try to pull data from the db then my url is working after deploy.
How can i get the data ?
My data in the local.settings.json was wrong. I had azure storage for other table not for the one that i wanted to query... The code works perfectly fine
When building an application in Azure Functions you can specify the HTTP Methods that are accepted in the function.json
Given an API that you can do multiple functions on (GET, PUT POST etc) what is the best way to create that function or functions.
There will be shared logic and libraries that need to be available, so I'm looking for a pattern that can enable all the MEthods in a single class, but not sure how you would define that in a function.json such that each HTTP Method could have its own entry point.
The other option is to create a function that basically chooses the method and class that function but this seems like some middleware overhead that I"m sure can be handled in a better way.
i.e. I don't think I should do this for every object that I create a function for and there must be a better pattern.
async HandleRequest(){
return validateJwt(function(context,req){
if(req.method === 'GET'){
}
else if(req.method === 'POST'){
}
else if(req.method === 'DELETE'){
}
else if(req.method === 'PUT'){
}
else if(req.method === 'PATCH'){
}
});
}
So the best method for this is to use multiple functions.
You can define functions by route and method in the function.json file.
see the example.
Notice route:family/{id:int} this is the only route that this function will handle. you also put in the "methods": ["get"] To restrict the function to a GET.
Create a function per METHOD to have more maintainability in your code. I then use some middleware functionality (which does auth and error handling) before I have a common FamilyHandler Class that does the CRUD operations, including managing the connection to the database.
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get"],
"route": "family/{id:int}"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
I discovered this in the following documentation https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=javascript
Your function.json should like this:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
By default, if methods is not specified, then the function accepts all methods.
I'm creating a live chat using Azure functions and signalR. It works perfectly fine locally, but the deployed "negotiate" function does not work.
negotiate function (index.js)
module.exports = function (context, req, connectionInfo) {
context.res = { body: connectionInfo };
context.done();
}
config file (function.json)
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"direction": "in",
"connectionStringSetting": "AzureSignalRConnectionString"
}
]
}
AzureSignalRConnectionString is set in function app properties.
I also tried using "connectionString" instead of "connectionStringSetting" and using the connection string instead of "AzureSignalRConnectionString" reference, and all 4 possible combinations we have here.
If I run the function in Azure portal, I get this error:
[Error] Executed 'Functions.negotiate' (Failed, Id=0ac24b1f-1ab0-40f5-9680-34db547e1cc9)
Unable to resolve the value for property 'SignalRConnectionInfoAttribute.ConnectionStringSetting'. Make sure the setting exists and has a valid value
Did you write "connectionStringSetting" as the attribute name in your code ? If so, could you please have a try to change it to "ConnectionStringSetting". You may refer to this tutorial or the screenshot I post below:
Solved (got an answer on https://social.msdn.microsoft.com/).
I should have added the AzureSignalRConnectionString in FunctionApp/Configuration/Application settings instead of FunctionApp/Configuration/Application settings/Connection strings.
In order to prevent OPTIONS preflight requests being sent to an Azure Function, I want to add the Access-Control-Max-Age header to the OPTIONS response so that the browser caches the response for a given time.
I tried to create an Azure Proxy Function with this proxies.json file:
{
"proxies": {
"AddCacheHeaderToCorsPreflightResponse": {
"debug": true,
"matchCondition": {
"methods": [
"OPTIONS",
"GET"
],
"route": "/api/{rest}"
},
"backendUri": "http://%WEBSITE_HOSTNAME%/api/{rest}",
"responseOverrides": {
"response.headers.Access-Control-Max-Age": "31536000"
}
}
}
}
But this fails to add the response header to the OPTIONS request, but, for testing purposes, I can get GET responses to return the header. It appears that Azure doesn't allow you to add proxy functions for OPTIONS requests.
Is there a way to do this in Azure?
You need to make sure that your function.json contains OPTIONS in the methods array, like so:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": ["get", "post", "options"]
}
]
}
When you configure your httptrigger function, click Integrate and choose the OPTIONS method. Alternatively, you can remove the methods array entirely and allow all methods.