Azure Functions with Table Storage
Using a HTTP Trigger Azure Function and storing the data into an Azure Table storage account. Azure Table storage is a service that stores structured NoSQL data in the cloud, providing a key/attribute store with a schemaless design.
You can find the code for this here
This post builds on some other posts I've done,
I've covered getting started on Azure Table Storage in an other post Azure Table Storage
I've also covered creating a HTTP Trigger Azure Function
So let's get too it.
Adding Table Storage
In the project.json file we need to add the nuget reference for "WindowsAzure.Storage" as of writing this post the current version is 8.4.0. Our project.json will look something like this.
{
"frameworks":
{
"net46":
{
"dependencies":
{
"Newtonsoft.Json": "10.0.3",
"WindowsAzure.Storage": "8.4.0"
}
}
}
}
I've also got "Newtonsoft.Json" there because I want to use the Deserialize on the payload.
HTTP Trigger Function
Now over to our function in the run.csx and first we need our classes I have two. Our function will look something like this
using System.Net;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
dynamic body = await req.Content.ReadAsStringAsync();
var e = JsonConvert.DeserializeObject<Person>(body as string);
// Define the row,
string sRow = e.email + e.lastname;
// Create the Entity and set the partition to signup,
PersonEntity _person = new PersonEntity("signup", sRow);
_person.First_Name_VC = e.firstname;
_person.Last_Name_VC = e.lastname;
_person.Email_VC = e.email;
// Connect to the Storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("XXX");
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("personitems");
table.CreateIfNotExists();
TableOperation insertOperation = TableOperation.Insert(_person);
table.Execute(insertOperation);
return req.CreateResponse(HttpStatusCode.OK, "Ok");
}
public class Person{
public string firstname {get;set;}
public string lastname {get;set;}
public string email {get;set;}
}
public class PersonEntity : TableEntity
{
public PersonEntity(string skey, string srow)
{
this.PartitionKey = skey;
this.RowKey = srow;
}
public PersonEntity() { }
public string First_Name_VC { get; set; }
public string Last_Name_VC { get; set; }
public string Email_VC { get; set;}
}
So lets break it down and take a look
Person Class and PersonEntity
At the bottom of our Function we add our classes we want to use.
public class Person{
public string firstname {get;set;}
public string lastname {get;set;}
public string email {get;set;}
}
This person class is for the payload.
public class PersonEntity : TableEntity
{
public PersonEntity(string skey, string srow)
{
this.PartitionKey = skey;
this.RowKey = srow
}
public PersonEntity() { }
public string First_Name_VC { get; set; }
public string Last_Name_VC { get; set; }
public string Email_VC { get; set;}
}
This is our Table storage entity.
References
Next at the top we need to add our references
using System.Net;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
From HTTP Trigger to Table Storage
Now that's the house keeping done, lets walk through our function and save our information into Azure table storage.
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
dynamic body = await req.Content.ReadAsStringAsync();
var e = JsonConvert.DeserializeObject<Person>(body as string);
// Define the row,
string sRow = e.email + e.lastname;
// Create the Entity and set the partition to signup,
PersonEntity _person = new PersonEntity("signup", sRow);
_person.First_Name_VC = e.firstname;
_person.Last_Name_VC = e.lastname;
_person.Email_VC = e.email;
// Connect to the Storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("XXX");
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("personitems");
table.CreateIfNotExists();
TableOperation insertOperation = TableOperation.Insert(_person);
table.Execute(insertOperation);
return req.CreateResponse(HttpStatusCode.OK, "Ok");
}
First up we want to Deserialise our payload and turn it into an object.
dynamic body = await req.Content.ReadAsStringAsync();
var e = JsonConvert.DeserializeObject<Person>(body as string);
dynamic body reads the Content of the HttpRequestMessage req.
We tehn pass that into the JsonConvert as a string. JsonConvert DeserializeOject turns that into an object we can use.
Next we create our table entity.
// Define the row,
string sRow = e.email + e.lastname;
// Create the Entity and set the partition to signup,
PersonEntity _person = new PersonEntity("signup", sRow);
_person.First_Name_VC = e.firstname;
_person.Last_Name_VC = e.lastname;
_person.Email_VC = e.email;
Table Storage uses a partition key and row key for each object. That's up to you to set. In this case I have set the partition to signup. The RowKey should be unique to the partition. I've set by combining the email and last name. In a real world I would only allow the email in my Table storage once, so I would validate I had no new ones. So email could a rowkey you can set it according to your use case.
Next we setup our Person object and set the properties.
// Connect to the Storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("XXX");
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("personitems");
table.CreateIfNotExists();
TableOperation insertOperation = TableOperation.Insert(_person);
table.Execute(insertOperation);
We connect to our storage account, load our table of "personitems" I've added a check to create if not exists.
We then call the tableOperation and insert our new record to the database.
Wrap up
To end I have the function return OK, in the real world you might want more information here.
return req.CreateResponse(HttpStatusCode.OK, "Ok");
We now have a function that takes a HTTP payload and stores it into an Azure function.
Expanding Functions
One of the great things about functions is you can create bindings on other things. So you could have another function that runs when an entry is made in Azure Table Storage. That trigger would do another job with the new person that has just signed up.
That's it for this one for more on Azure Functions and serverless check out the series of posts I've created here