August 23rd, 2016

Creating a Serverless Backend for Mobile Apps

James Montemagno
Principal Manager, Tech PM

Azure Functions Functions_Logoenable 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.

Monkeys

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.


        
          

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:

public class Monkey
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string Image { 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.

public class MonkeysViewModel
{
    public MonkeysViewModel()
    {
        Monkeys = new ObservableRangeCollection();
        GetMonkeysCommand = new Command(async () => await GetMonkeysAsync());
    }
    
    //Monkey List: ObservableRangeCollection from: https://github.com/jamesmontemagno/mvvm-helpers
    public ObservableRangeCollection Monkeys { get; set; }

    //Selected Location index from our picker
    public int Location { get; set; }

    //Mirror list so we can use it later
    public List LocationList => new List
    {
        "Africa",
        "Asia",
        "Central America",
        "South America"
    };

    //Command that will call GetMonkeysAsync to get data
    public Command GetMonkeysCommand { get; }

    public async Task 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.

public MonkeysPage()
{
    InitializeComponent();
    BindingContext = new MonkeysViewModel();
}

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.

NewFunction

Once created, we’ll see boilerplate code that parses the request for a field called “name” that we can use later on.

public static async Task Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info($"C# HTTP trigger function processed a request. RequestUri={req.RequestUri}");
    
    // parse query parameter
    string name = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
        .Value;

    // Get request body
    dynamic data = await req.Content.ReadAsAsync();

    // Set name to query string or body data
    name = name ?? data?.name;
    

    return name == 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.

New Input

There are several options, including integrating with Azure Mobile Table Records or existing SaaS solutions, for file and table access: AddSaas

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:

var monkeys =  GetMonkeys().Where(m => m.Location.ToLower().Contains(name.ToLower()));
    
return name == 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.

public async Task GetMonkeysAsync()
{
    try
    {
        using (var client = new HttpClient())
        {
            var url = "https://mobile-ocr.azurewebsites.net/api/Monkeys";

            var input = JsonConvert.SerializeObject(new { name = LocationList[Location] });
            var res = await client.PostAsync(url,
                new StringContent(input, Encoding.UTF8,"application/json"));

            var json = await res.Content.ReadAsStringAsync();

            var monkeys = JsonConvert.DeserializeObject<IEnumerable>(json);

            Monkeys.ReplaceRange(monkeys);
        }
    }
    catch (System.Exception ex)
    {
        //Something has gone wrong
        Debug.WriteLine(ex);

    }
} 

In Action

In Motion

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.

Author

James Montemagno
Principal Manager, Tech PM

James Montemagno is a Principal Lead Program Manager for Developer Community at Microsoft. He has been a .NET developer since 2005, working in a wide range of industries including game development, printer software, and web services. Prior to becoming a Principal Program Manager, James was a professional mobile developer and has now been crafting apps since 2011 with Xamarin. In his spare time, he is most likely cycling around Seattle or guzzling gallons of coffee at a local coffee shop. He ...

More about author

0 comments

Discussion are closed.