Using F# with Table Storage and Azure Functions
Tags: fsharp, azurefunctions, serverless, azure
Published: 2019-07-12 05:49:11

---
title: Using F# with Table Storage and Azure Functions
published: true
tags: fsharp,azure-functions,serverless,azure
canonical_url: https://www.aaron-powell.com/posts/2019-07-12-using-fsharp-with-table-storage-and-azure-functions/
---

I've been doing a lot of work recently with [Azure Functions](https://azure.microsoft.com/en-us/services/functions/?WT.mc_id=devto-blog-aapowell) in which I use [Table Storage](https://azure.microsoft.com/en-us/services/storage/tables/?WT.mc_id=devto-blog-aapowell) as the backend for it. This led me to start using the [FSharp.Azure.Storage](https://github.com/fsprojects/FSharp.Azure.Storage) NuGet package which gives a nicer API for Table Storage (and also happens to be written by a former colleague of mine).

But there's a catch, `FSharp.Azure.Storage` is designed to work with the `CloudTableClient` which you would normally get like so:

```
open Microsoft.WindowsAzure.Storage
open Microsoft.WindowsAzure.Storage.Table

let account = CloudStorageAccount.Parse "UseDevelopmentStorage=true;" //Or your connection string here
let tableClient = account.CreateCloudTableClient()

let inGameTable game = inTable tableClient "Games" game

```

But when we're using an Azure Function we're likely doing a binding in our Function parameter, like this:

```
[<FunctionName("Some_Function")>]
let someFunction ([<HttpTrigger(AuthorizationLevel.Function, "get", Route = "some-function")>] req: HttpRequest)
                 ([<Table("MyData")>] dataTable: CloudTable) =
    // do stuff

```

Notice that here we'll receive a `CloudTable`, which has already been created from the `CloudTableClient`. This is because Azure Functions takes care of the creation and "connection pooling" (for lack of a better description) so that we don't need to do it ourselves as the Functions scale. We also need the name of the table that we're working with, again we don't need to worry about that in our Function, since we already have the `CloudTable`.

Thankfully, we can go from a `CloudTable` back to the `CloudTableClient` and get the name of the table at the same time. To do this I’ve created some new functions in my F# codebase:

```
module azureTableUtils
open FSharp.Azure.Storage.Table
open Microsoft.WindowsAzure.Storage.Table

let fromTableToClientAsync (table: CloudTable) q = fromTableAsync table.ServiceClient table.Name q
let fromTableToClient (table: CloudTable) q = fromTable table.ServiceClient table.Name q

let inTableToClientAsync (table: CloudTable) o = inTableAsync table.ServiceClient table.Name o
let inTableToClient (table: CloudTable) o = inTable table.ServiceClient table.Name o

let inTableToClientAsBatch (table: CloudTable) o = inTableAsBatch table.ServiceClient table.Name o
let inTableToClientAsBatchAsync (table: CloudTable) o = inTableAsBatchAsync table.ServiceClient table.Name o

```

From the `CloudTable` you can access the `ServiceClient` to get the `CloudTableClient` and `Name` gives you the name!

Now we can use it in our Azure Function like so:

```
[<FunctionName("Some_Function")>]
let someFunction ([<HttpTrigger(AuthorizationLevel.Function, "get", Route = "some-function")>] req: HttpRequest)
                 ([<Table("MyData")>] dataTable: CloudTable) =
    async {
        let! data = Query.all<MyData>
                    |> fromTableToClientAsync dataTable

        let! data
             |> Seq.map (fun (d, _) ->
                 { d with Value = "Updated" })
             |> Replace
             |> autobatch
             |> List.map (inTableToClientBatch dataTable)
             |> Async.Parallel

        return OkResult() :> IActionResult
    } |> Async.StartAsTask

```

Feel free to use those functions in your own applications. You will have to explcitly type the `table` argument as `CloudTable` as the F# type inference isn't able to pick up that that’s what it is otherwise.

Happy F#'ing!