Additional Parameter in Node Azure Function - node.js

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

Related

Azure Function binding error for signalR (negotiate function) (500 error code)

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.

Adding Access-Control-Max-Age to Azure Functions

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.

When I am running azure HTTP Trigger function i am getting 401 unauthorized

I am trying to run Azure HTTP Trigger Azure Function and I am receiving a 401 Unauthorized. It was working fine for me earlier.
When I created the new function under the same Function App and copied the same code then also it is running fine but when I am trying to run my created function then I am getting the same error that I mentioned.
I'm seeing the following logs in the streaming service.
2018-07-02T07:09:41 Welcome, you are now connected to log-streaming service.
2018-07-02T07:09:48.893 [Info] Executing HTTP request: {
"requestId": "53e54698-c46b-4cb6-9ed0-d042eaf9ec71",
"method": "POST",
"uri": "/api/Source/MPAA/false"
}
2018-07-02T07:09:48.893 [Info] Executed HTTP request: {
"requestId": "53e54698-c46b-4cb6-9ed0-d042eaf9ec71",
"method": "POST",
"uri": "/api/Source/MPAA/false",
"authorizationLevel": "Anonymous",
"status": "Unauthorized"
}
This is how I solved the problem based on the cause correctly provided by Nick above. Do this if you don't want to have to open the Azure Function's GUI every time you push your code.
In the source code of the function:
[FunctionName("YourFunctionName")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log){
What I had to do was to change the default setting AuthorizationLevel.Function into AuthorizationLevel.Anonymous. The former only allows triggering from other Function apps, the later will let you trigger from the browser.
If you are managing your code via the azure portal, then simply navigate to "Integrate" and change the "Authorization Level" drop-down to "Anonymous".
If you are managing your code with source control integration (e.g. via git), add this to your function.json:
"authLevel": "anonymous"
Full snippet of function.json:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [ "post" ],
"route": "Source/MPAA",
"authLevel": "anonymous"
},
{
"type": "http",
"name": "res",
"direction": "out"
}
],
"disabled": false
}
Note: the above is just an example, you may have to tweak the route.
Note: the /api is the default prefix, and can be modified in the host.json file.
Its about the authlevel of the function.
If you use the authlevel = anonymous in you function.json file. Then you don't have to pass any access key and you can access the azure function api like the normal api endpoints.
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
For example you http trigger is http://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME> you can easily access this without any access/auth key.
If your are using the authlevel = function then you have to pass the access key/Api key with the http trigger endpoint while hitting it. If you don't you will get the 401 unauthorized.
{
"disabled": false,
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
You need to pass the key like as below example.
**https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>
**
For the authlevel = function you can access the http trigger by the function key
and the host key. You will find the Get Function Url section when you open the function in the azure portal.
Note
With the host key you can access all of your http trigger endpoints its going to be common for all the http trigger. But the function key is unique for every function.
The third option is to use the authlevel = admin.
{
"disabled": false,
"bindings": [
{
"authLevel": "admin",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
For auth level admin the http trigger can only be access by the master key.
**https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<MASTER_KEY>
**
You will find all these keys as per the auth levels in the Get Function Url section.
The complete guide for the authlevel is in this link.
Azure Functions HTTP trigger function authlevel Explanation
I hope this will be helpfull.
I started getting 401's too until I realised that I had two functions with the same route. That obviously confused Azure big time.
Check if you don't have different functions with same routes.
I started seeing this response after changing the function runtime version via Azure Portal. Redeploying the function app from Visual Studio resolved the issue for me.

How to customize Azure function url

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": "".

Azure functions pre-compiled function, HttpRequestMessage not being passed to function

I have the following F# function signature and beginning of function
let Run(req: HttpRequestMessage, log: TraceWriter) =
async {
log.Info("HttpRequestMessage" + req.ToString())
...
when I execute my function and print the value of req I get
HttpRequestMessageMethod: GET, RequestUri: '<null>', Version: 1.1, Content:
<null>, Headers:{ }
Below is my function.json file
{
"scriptFile": "../WonkTonkLib/wonktonkPostLib.dll",
"entryPoint": "PutUser.Run",
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"post"
]
},
{
"name": "res",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
Any idea why I the request message isn't being passed to the function? Any help is appreciated.
Please make sure your project is referencing System.Net.Http 4.1.1.0 and not a later version.
The current tools and the runtime are both being updated to address this without that requirement, but in the meantime, making sure you're matching that version should address this issue.

Resources