How to call another function with in an Azure function

I have written 3 functions as follows

  1. create users in db
  2. fetch users from db
  3. process users

In [3] function, I will call [2] function to get users using Azure function url as below:-

https://hdidownload.azurewebsites.net/api/getusers

Is there any other way to call Azure function with in another Azure function without full path as above?

Enquirer: Galet

||

Solution #1:

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.

Respondent: Mikhail Shilkov

Solution #2:

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:

  • The main sequence chains up two additional functions that are run after one another
  • When an external function is executed, the main sequence is put to sleep; this means that you won’t be billed twice once an external function is busy processing

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:

Respondent: Juliƫn

Solution #3:

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;
    }

}
Respondent: Juan Mitchell

Solution #4:

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).

  1. Send an HTTP request to another function’s public URL
  2. Put a message into an Azure Queue and let the other Azure Function process it
  3. Use Durable Functions

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.

Respondent: Artemious

Solution #5:

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.

Solution #6:

Durable functions support this, however, they are currently supported only when using C#, F# or JavaScript.

Another options would be

  1. 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.

  1. Use Azure Storage Queues. First function passes message to a queue, which will trigger another Azure function. That seems more elegant solution. As Fabio writes here:

This keeps your functions small, fast and decoupled, while taking
advantage of all the logic in place for provisioning, scaling and
fault handling.

Respondent: itzprintz

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.