I have written 3 functions as follows
In [3] function, I will call [2] functi
I know we have Durable Functions but I call my functions like a normal static method and it works, here an example :
public static class HelloWorld
{
[FunctionName("HelloWorld")]
public static string Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)
{
return "Hello World";
}
}
public static class HelloWorldCall
{
[FunctionName("HelloWorldCall")]
public static string Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log)
{
var caller = HelloWorld.Run(req, log);
return caller;
}
}
There's nothing built-in in Function Apps to call one HTTP function from other functions without actually making the HTTP call.
For simple use cases I would just stick to calling by full URL.
For more advanced workflows, have a look at Durable Functions, paticularly Function Chaining.
You can do it directly by calling the 2nd function as a normal C# static method.
But in this case you lose benefits of Azure Functions scaling and distributing (for example, based on server load your 2nd function may be called from different part of the world).
As for the 1st option in C# you can do it like so:
static HttpClient client = new HttpClient();
[FunctionName("RequestImageProcessing")]
public static async Task RequestImageProcessing([HttpTrigger(WebHookType = "genericJson")]
HttpRequestMessage req)
{
string anotherFunctionSecret = ConfigurationManager.AppSettings
["AnotherFunction_secret"];
// anotherFunctionUri is another Azure Function's
// public URL, which should provide the secret code stored in app settings
// with key 'AnotherFunction_secret'
Uri anotherFunctionUri = new Uri(req.RequestUri.AbsoluteUri.Replace(
req.RequestUri.PathAndQuery,
$"/api/AnotherFunction?code={anotherFunctionSecret}"));
var responseFromAnotherFunction = await client.GetAsync(anotherFunctionUri);
// process the response
}
[FunctionName("AnotherFunction")]
public static async Task AnotherFunction([HttpTrigger(WebHookType = "genericJson")]
HttpRequestMessage req)
{
await Worker.DoWorkAsync();
}
Also sometimes you need your first Azure Function to return HTTP response first, and then do something in the background, so this solution won't work. In this case options 2 and 3 are suitable.
Durable functions support this, however, they are currently supported only when using C#, F# or JavaScript.
Another options would be
Create HTTP request for new Azure function, however, you would have to do it in a way where your function doesn't wait for response, otherwise first function in a chain would have to wait until the very last one finishes. Using Python, that would be something like:
try:
requests.get("http://secondAzureFunction.com/api/",timeout=0.0000000001)
except requests.exceptions.ReadTimeout:
pass
That seems bit hacky to me though.
This keeps your functions small, fast and decoupled, while taking advantage of all the logic in place for provisioning, scaling and fault handling.
I din't find any good sources, I did the below, it worked fine.
To call other function with its url, of below format:
https://my-functn-app-1.azurewebsites.net/some-path-here1?code=123412somecodehereemiii888ii88k123m123l123k1l23k1l3==
In Node.js, I called as below:
let request_options = {
method: 'GET',
host: 'my-functn-app-1.azurewebsites.net',
path: '/path1/path2?&q1=v1&q2=v2&code=123412somecodehereemiii888ii88k123m123l123k1l23k1l3',
headers: {
'Content-Type': 'application/json'
}
};
require('https')
.request(
request_options,
function (res) {
// do something here
});
Worked with no issues.
It should work similar way for other programming languages.
Hope this helps.
All the previous answers are valid but, as was also mentioned in the comments, earlier this year (Q1/Q2 2018) the concept of Durable Functions has been introduced. In short, Durable Functions:
... lets you write stateful functions in a serverless environment. The extension manages state, checkpoints, and restarts for you.
This effectively means that you can also now chain several Functions together. It manages state when it flows from Function A => B => C, if you would require this.
It works by installing the Durable Functions Extension to your Function App. With that, you have some new context bindings available where, for example in C#, you can do something like (pseudo code):
[FunctionName("ExpensiveDurableSequence")]
public static async Task<List<string>> Run(
[OrchestrationTrigger] DurableOrchestrationTrigger context)
{
var response = new List<Order>();
// Call external function 1
var token = await context.CallActivityAsync<string>("GetDbToken", "i-am-root");
// Call external function 2
response.Add(await context.CallActivityAsync<IEnumerable<Order>>("GetOrdersFromDb", token));
return response;
}
[FunctionName("GetDbToken")]
public static string GetDbToken([ActivityTrigger] string username)
{
// do expensive remote api magic here
return token;
}
[FunctionaName("GetOrdersFromDb")]
public static IEnumerable<Order> GetOrdersFromDb([ActivityTrigger] string apikey)
{
// do expensive db magic here
return orders;
}
Some nice aspects here are:
This allows you to both run multiple functions in sequence of each other (e.g. function chaining), or execute multiple functions in parallel and wait for them all to finish (fan-out/fan-in).
Some additional background reference on this: