Azure Functions: Map Data to Output Bindings
From Azure Functions, we can map data to Output bindings using following three options.
- Using function return value
- Using out parameter
- 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.