Consuming Azure Functions

This document outlines various methods and best practices for consuming Azure Functions from different clients and services.

HTTP Triggered Functions

Functions configured with an HTTP trigger are the most common way to expose serverless logic to external callers. They can be invoked using standard HTTP requests.

Invoking via HTTP Clients

You can use any standard HTTP client, such as curl, Postman, or programming language libraries (e.g., fetch in JavaScript, HttpClient in C#, requests in Python), to call your HTTP-triggered functions.

Example using curl:

curl -X POST "https://your-function-app-name.azurewebsites.net/api/my-http-trigger?code=YOUR_FUNCTION_KEY" \
    -H "Content-Type: application/json" \
    -d '{
        "name": "Azure Functions User",
        "message": "Hello from curl!"
    }'

Note: Replace your-function-app-name, my-http-trigger, and YOUR_FUNCTION_KEY with your actual values. The code query parameter is used for authorization if your function requires a key.

Invoking via JavaScript (Fetch API)

const url = 'https://your-function-app-name.azurewebsites.net/api/my-http-trigger';
const data = {
    name: "Azure Functions User",
    message: "Hello from JavaScript!"
};

fetch(url, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'x-functions-key': 'YOUR_FUNCTION_KEY' // If using function key authorization
    },
    body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

Binding to Other Azure Services

Azure Functions can be triggered by or interact with a wide range of Azure services using input and output bindings. This allows seamless integration without writing boilerplate code for service communication.

Example: Queue Triggered Function Writing to Blob Storage

A function triggered by a message on an Azure Queue can process the message and write the result to an Azure Blob Storage container.

Function.json (Simplified):

{
  "bindings": [
    {
      "name": "message",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "my-input-queue",
      "connection": "AzureWebJobsStorage"
    },
    {
      "name": "outputBlob",
      "type": "blob",
      "direction": "out",
      "path": "my-output-container/{rand-guid}.txt",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

Code (Example - JavaScript):

module.exports = async function (context, message) {
    context.log('JavaScript queue trigger function processed work item', message);
    const outputText = `Processed message: ${message.text}`;
    context.bindings.outputBlob = outputText;
    context.done();
};

Calling Functions from Other Functions

You can invoke other Azure Functions from within your existing functions, creating complex workflows and microservice architectures.

Using the Function Invocation API

The Azure Functions runtime provides an API to invoke other functions. This is particularly useful for Durable Functions or orchestrating sequential tasks.

HTTP Client within a Function

You can also use standard HTTP clients within a function's code to call HTTP-triggered functions.

Example within a C# Function:

using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

public static async Task Run(string input, ILogger log)
{
    log.LogInformation($"C# ServiceBus topic trigger function processed message: {input}");

    using (var client = new HttpClient())
    {
        var triggerUrl = "https://your-function-app-name.azurewebsites.net/api/another-function";
        var payload = new { message = $"Processed from {Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME")}" };
        var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");
        
        // Include authorization key if needed
        client.DefaultRequestHeaders.Add("x-functions-key", "ANOTHER_FUNCTION_KEY");

        var response = await client.PostAsync(triggerUrl, content);
        if (response.IsSuccessStatusCode)
        {
            log.LogInformation("Successfully invoked another function.");
        }
        else
        {
            log.LogError($"Failed to invoke another function. Status: {response.StatusCode}");
        }
    }
}

Best Practices for Consumption