Share via


Azure Functions: Map Data to Output Bindings

From Azure Functions, we can map data to Output bindings using following three options.

  1. Using function return value
  2. Using out parameter
  3. Using ICollector or IAsyncCollector

In this article let’s have a look at them in detail. Let's assume we already have created a Azure Function App using the Azure Portal and we will be using portals’ editor in this post.

The scenario we are going use is, we will have a Azure Function which can be triggered manually. From there we will be outputting messages to a Azure Storage Queue.

So first let’s create a Queue trigger.

https://lh3.googleusercontent.com/-5WPyyVGCY1U/WrEA-IeOKVI/AAAAAAAAEyw/HsRUoYSRO20f9InWIAHcaIoT-YUr5EE8gCHMYCw/image_thumb%255B15%255D?imgmax=800
Queue trigger
https://lh3.googleusercontent.com/-xpR5hEelHG4/WrEA_uEvO0I/AAAAAAAAEy4/wq9XH4-PaSMmcW_YWCopOT3oV0NekBQMgCHMYCw/image_thumb%255B18%255D?imgmax=800
Queue trigger Properties
using System;
  
public static void Run(string myQueueItem, TraceWriter log)
{
    log.Info($"Queue trigger function processed: {myQueueItem}");
}

So every time a message get queued to myqueue-demo, QueueTriggerCSharp1 function will get triggered. It will just log the message, so we can see whether the data is getting correctly mapped when we are using Output bindings in our Manual trigger.

Now let’s create the Manual trigger.

https://lh3.googleusercontent.com/-s4TpjShWOYs/WrEBAxv8ZQI/AAAAAAAAEzA/D9eAOSoFZ9kDD_m2zBePgUGMO44Mm1XxwCHMYCw/image_thumb%255B20%255D?imgmax=800
Manual trigger
https://lh3.googleusercontent.com/-1FK_urgfoUg/WrEBCZToYKI/AAAAAAAAEzI/_hgmOHs9Q54dcbuqCZZsXjLMX0AwbjSYwCHMYCw/image_thumb%255B23%255D?imgmax=800
Manual trigger Properties
using System;
  
public static void Run(string input, TraceWriter log)
{
    log.Info($"Manually triggered function called with input: {input}");
}

1. Using function return value

The most easiest way to map data to Output binding is using the functions return value.

Let's change our ManualTriggerCSharp1 as follows.

using System;
  
public static string Run(string input, TraceWriter log)
{
    log.Info($"Manually triggered function with input: {input}");
    return $"Using Return: {input}";
}

Now we have a function which returns a string. Our requirement is map this return value to a Output binding.

For that, let’s go to Integrate menu under our ManualTriggerCSharp1 function.

https://lh3.googleusercontent.com/-ClHP4OGE74k/WrEBEYEl1BI/AAAAAAAAEzQ/_YbIqoHV7XkQ0fEL14Ry50WrJgJvdC5lACHMYCw/image_thumb%255B25%255D?imgmax=800
Integrate

And you will see something like below.

https://lh3.googleusercontent.com/-9Rvaj1_IXcQ/WrEBFxn6L5I/AAAAAAAAEzY/gLsSiXdYxYcZQ_8Qy_SirBwQwwYYbD1DwCHMYCw/image_thumb%255B28%255D?imgmax=800
Integrate

Click on New Output under Outputs. Select Azure Queue Storage.

https://lh3.googleusercontent.com/-hrgkC9AieyA/WrEBHQ9xMoI/AAAAAAAAEzg/xFacOWdg8SsljNZYBVnPGoo_DU2ZNLHzQCHMYCw/image_thumb%255B30%255D?imgmax=800
Select Output Type

From next wizard page, you can simply select the “Use function return value”. Then you will need to select the Queue name and it’s Storage account connection which you want to write the output into.

https://lh3.googleusercontent.com/-NAcAQLG__8k/WrEBIyI6csI/AAAAAAAAEzo/Pub1L_iAS94XuASE0ToPaCFM26aSLO-ZQCHMYCw/image_thumb%255B32%255D?imgmax=800
New Output Properties

Click on Save, and run our Manual trigger. After running it, if you go to Monitor menu under QueueTriggerCSharp1, you can see the return value has been read.

https://lh3.googleusercontent.com/-BuV1Verhk5g/WrEBKeSUN3I/AAAAAAAAEzw/-FLrJf8WxNY2dPi_s0xRx-drMQ5i8INewCHMYCw/SNAGHTML1ec1504c_thumb%255B2%255D?imgmax=800
Monitor
https://lh3.googleusercontent.com/-o4Cm4SAxEbg/WrEBLts7ZWI/AAAAAAAAEz4/HK1-yDLSPOYE76XPoLygMxFQyt9gmVOGQCHMYCw/image_thumb%255B34%255D?imgmax=800
Monitor

2. Using out parameter

Now let’s modify our ManualTriggerCSharp1 function to have out parameter and set it’s value in the function body.

using System;
  
public static string Run(string input, TraceWriter log, out string outParameter)
{
    log.Info($"Manually triggered function with input: {input}");
  
    outParameter = $"Using Out: {input}";
 
    return $"Using Return: {input}";
}

Now let’s add this Output binding.

Again add a New Output and select Azure Queue Storage and then do as following (remember to specify the correct Queue name which our QueueTriggerCSharp1 is watching).

https://lh3.googleusercontent.com/-rovLsU5CTiw/WrEBMxRY7mI/AAAAAAAAE0A/ySJ7brRQ9L0fFaYj9BSm_lvPGpxse022gCHMYCw/image_thumb%255B36%255D?imgmax=800
New Output Properties

Important thing to keep in mind is Message parameter name needs to be same as your out parameter name.

Save and run the manual trigger and examine the Monitor menu under QueueTriggerCSharp1.

Now you should be seeing the value of out parameter has been added to the queue and is read.

https://lh3.googleusercontent.com/-f0T2f3ZwZfg/WrEBO4cFSNI/AAAAAAAAE0I/ErFkbsnQKuEPlxq1KMJR542YYBbVDSmwQCHMYCw/image_thumb%255B39%255D?imgmax=800
Monitor

Now what if the function is an async one. Then we can’t use out parameters.

3. Using ICollector or IAsyncCollector

This is most preferred way of mapping data to Output bindings. One reason of course is most of the time, functions are async. And the other reason is, using Collectors we can pass multiple data. Let’s modify the ManualTriggerCSharp1 as follows.

using System;
  
public static async Task<string> Run(string input, TraceWriter log, IAsyncCollector<string> queueCollector)
{
    log.Info($"Manually triggered function with input: {input}");
  
    await queueCollector.AddAsync($"Using Collector: {input} 1");
    await queueCollector.AddAsync($"Using Collector: {input} 2");
  
    return $"Using Return: {input}";
}

Right now since we don’t have the existing outParameter and it’s binding, let’s change the previous Output binding.

https://lh3.googleusercontent.com/-37DViXG3Cw0/WrEBQvd8i-I/AAAAAAAAE0Q/zPBJbGYz_M4U0pFxuLOsfgf_CJuQq8JeQCHMYCw/image_thumb%255B41%255D?imgmax=800
Output Properties

Again, we need to make sure Message parameter name is the same as the function parameter name.

And if we save and run, we should be seeing the message is queued and read by QueueTriggerCSharp1.

https://lh3.googleusercontent.com/-Y8qKmkZVcEA/WrEBSQbIqxI/AAAAAAAAE0Y/SM1rtRE_6IQEYaFNfleq660qZMYOPpZUgCHMYCw/image_thumb%255B43%255D?imgmax=800
Monitor

And note: ICollector is the synchronous counterpart of IAsyncCollector.