Azure Functions enable developers to create a serverless, event-driven experience for their data and applications. In our first post on Azure Functions, we saw how to have an Azure Function perform an OCR of an image and insert it into an Azure Mobile table. Today, we’re going to take a look at turning Azure Functions into a serverless backend for our mobile apps that can integrate and connect with data from Azure, Office, Salesforce, or even Google Docs.
In this blog post, we’ll create a new mobile app that can query data through a single Azure Function endpoint. The Azure Function we create will take a country as input to a HttpRequest
, parse data from a data source, and return a list of monkeys that live in that region.
Creating our Mobile App
To get started, we need to create a new blank Xamarin.Forms application and add a new XAML page for our user interface. The UI will have a few elements on it to select the location we want to query for monkeys from, a button to press to call our backend code, and a list of monkeys.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<ContentPage
xmlns=“http://xamarin.com/schemas/2014/forms”
xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml”
x:Class=“Monkeys.Views.MonkeysPage”
Title=“Monkeys”>
<StackLayout>
<Label Text=“Pick Location”Margin=“10,10,10,0”/>
<Pickerx:Name=“LocationPicker”Margin=“10,10,10,0”
SelectedIndex=“{Binding Location}”
HorizontalOptions=“FillAndExpand”>
<Picker.Items>
<x:String>Africa</x:String>
<x:String>Asia</x:String>
<x:String>Central America</x:String>
<x:String>South America</x:String>
</Picker.Items>
</Picker>
<Button Text=“Find Monkeys”
Margin=“10,10,10,0”
Command=“{Binding GetMonkeysCommand}”/>
<ListView ItemsSource=“{Binding Monkeys}”
HasUnevenRows=“true”>
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell ImageSource=“{Binding Image}”Text=“{Binding Name}
Detail=”{Binding Location}/>
<!—Custom ViewCell,or DefaultCell—>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
|
Now we’ve got our base page set up and ready to consume data from our Azure Function. Before we create the Azure Function, let’s set up our Model
and ViewModel
that our View
will talk to.
First is the Monkey
model, which has a few properties:
1
2
3
4
5
6
7
|
publicclassMonkey
{
publicstringName{get;set;}
publicstringLocation{get;set;}
publicstringDetails{get;set;}
publicstringImage{get;set;}
}
|
Then we can create our ViewModel
that the user interface will bind to, and we’ll also stub out a Command
that will call our Azure Function when the “Find Monkeys” button is pressed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
publicclassMonkeysViewModel
{
publicMonkeysViewModel()
{
Monkeys=newObservableRangeCollection<Monkey>();
GetMonkeysCommand=newCommand(async()=>awaitGetMonkeysAsync());
}
//Monkey List: ObservableRangeCollection from: https://github.com/jamesmontemagno/mvvm-helpers
publicObservableRangeCollection<Monkey>Monkeys{get;set;}
//Selected Location index from our picker
publicintLocation{get;set;}
//Mirror list so we can use it later
publicList<string>LocationList=>newList<string>
{
“Africa”,
“Asia”,
“Central America”,
“South America”
};
//Command that will call GetMonkeysAsync to get data
publicCommandGetMonkeysCommand{get;}
publicasyncTask GetMonkeysAsync()
{
try
{
//Call to Azure Function here
//Load Monkeys here.
}
catch(System.Exception ex)
{
Debug.WriteLine(ex);
}
}
}
|
Finally, in the code behind of our MonkeysPage.xaml.cs
, we can set the BindingContext
.
1
2
3
4
5
|
publicMonkeysPage()
{
InitializeComponent();
BindingContext=newMonkeysViewModel();
}
|
Now, it’s time to create our backend with Azure Functions to pull data into our mobile app.
Creating the Function
Creating an Azure Function to respond to a web request is simple, as there’s already a template called “HttpTrigger – C#” that will provide boilerplate code to take in an HTTPRequestMessage
and output a HttpResponseMessage
with any data we’d like. Name the function and set the authorization level to anonymous, so our mobile app can access the endpoint.
Once created, we’ll see boilerplate code that parses the request for a field called “name” that we can use later on.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
publicstaticasyncTask Run(HttpRequestMessage req,TraceWriter log)
{
log.Info($“C# HTTP trigger function processed a request. RequestUri={req.RequestUri}”);
// parse query parameter
stringname=req.GetQueryNameValuePairs()
.FirstOrDefault(q=>string.Compare(q.Key,“name”,true)==0)
.Value;
// Get request body
dynamicdata=awaitreq.Content.ReadAsAsync<objectwidth=“300”height=“150”>();
// Set name to query string or body data
name=name??data?.name;
returnname==null
?req.CreateResponse(HttpStatusCode.BadRequest,“Please pass a name on the query string or in the request body”)
:req.CreateResponse(HttpStatusCode.OK,“Hello “+name));
}
|
Note that for extra security we could turn on authentication for our Function with Azure Easy Authentication or a secret key.
Adding Data from Input Bindings
At this point, we could call the function endpoint and it will return a simple message to us. For our app, we want to take in the parameters, talk to a data source, and return data for our mobile app. This is where input bindings for Functions are handy. Tap on the Integrate tab and select New Input. This will enable us to create a connector to several data sources to read data from.
There are several options, including integrating with Azure Mobile Table Records or existing SaaS solutions, for file and table access:
For this example, we’ll skip this step and hard code in the monkey data that will be returned. We can use the name parameter as the location that is passed in.
This means before we return, we’ll get the list of monkeys and then perform a Linq query to find the monkeys with the specified location:
1
2
3
4
5
|
varmonkeys=GetMonkeys().Where(m=>m.Location.ToLower().Contains(name.ToLower()));
returnname==null
?req.CreateResponse(HttpStatusCode.BadRequest,“Please pass a name on the query string or in the request body”)
:req.CreateResponse(HttpStatusCode.OK,monkeys);
|
You can find the final run.csx file on my GitHub for reference.
Getting Data to our Mobile App
Now it’s time to integrate the Azure Function into our mobile applications. All we need to do is fill in our GetMonkeysAsync
method to make a web request and deserialize the data from our Azure Function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
publicasyncTask GetMonkeysAsync()
{
try
{
using(varclient=newHttpClient())
{
varurl=“https://mobile-ocr.azurewebsites.net/api/Monkeys”;
varinput=JsonConvert.SerializeObject(new{name=LocationList[Location]});
varres=awaitclient.PostAsync(url,
newStringContent(input,Encoding.UTF8,“application/json”));
varjson=awaitres.Content.ReadAsStringAsync();
varmonkeys=JsonConvert.DeserializeObject<IEnumerable<monkey>>(json);
Monkeys.ReplaceRange(monkeys);
}
}
catch(System.Exception ex)
{
//Something has gone wrong
Debug.WriteLine(ex);
}
}
|
In Action
There you have it! Our mobile app is able to call and pass data to our Azure Function and get the correct list of monkeys back.
Learn More
There are so many more integrations for Azure Functions for mobile applications, especially around Bindings and Triggers to tie to several data sources. Be sure to head to the Azure Functions website for more information and download the full source code for the sample app on my GitHub.