loading...
Microsoft Azure

Azure Functions With F#

aaronpowell profile image Aaron Powell Originally published at aaron-powell.com on ・3 min read

I’m starting to work on a new project in which I’m going to use Azure Functions v2 for a simple API backend.

Azure Functions support a number of different languages such as Java, Python (in preview at time of writing), TypeScript (and naturally JavaScript) and of course C#. So with all those to pick from what would I want to choose?

Well, naturally I decided to go with F#, which kind of worked in v1. And after all, it’s a CLR language so there’s no reason it shouldn’t work in v2 like C# does.

But unfortunately there’s no templates available, so getting started seems to be a bit trickier.

Creating an F# Functions Application

To create a F# Functions Application the easiest approach is to follow the Visual Studio Code instructions to get the extensions installed.

Once VS Code is ready to go we’ll create a new New Functions Project choosing C# as the language.

Now comes the tricky part, rename your csproj file to fsproj and add a reference to FSharp.Core.

And you’re done!

Ok, it wasn’t really that tricky was it! Since it’s all on the CLR and it’s a .NET Core application the dotnet cli tools will just work! You’ll even get debugging support from within VS Code of your F# Functions.

Now you’re ready to create a function with F#!

Here’s a basic HTTP trigger:

module HttpTrigger

open Microsoft.Azure.WebJobs
open Microsoft.AspNetCore.Mvc
open Microsoft.Azure.WebJobs.Extensions.Http
open Microsoft.AspNetCore.Http
open System.IO
open System.Text

[<FunctionName("HttpTrigger")>]
let httpTriggerFunction ([<HttpTrigger(AuthorizationLevel.Function, "post", Route = null)>] req : HttpRequest) =
    async {
        use reader = new StreamReader(req.Body, Encoding.UTF8)
        let! body = reader.ReadToEndAsync() |> Async.AwaitTask
        return OkObjectResult body
    } |> Async.StartAsTask

Be aware that if you’re doing anything with async you’ll need to convert it to Task<'T> for the return as the Functions host expects the C# Task API for async, not F#’s Async workflows 😦.

Caveat’s

There’s a minor caveat to this whole thing, because the VS Code extension doesn’t understand F# you can’t use it to add new functions to your project, you have to manually do it, and you then have to know what NuGet packages that you require are going to be. I find it easy enough to just have another VS Code window open and create a C# one if I need to look up types and their packages.

You’ll also find that the .vscode/settings.json file contains "azureFunctions.projectLanguage": "C#". You can change that to F# if you want, but it’ll give you a warning because the extension doesn’t understand it. I leave it as C# because it doesn’t bother me.

Conclusion

While the tooling might not be there, creating an Azure Function with F# really isn’t that big a deal.

Posted on by:

aaronpowell profile

Aaron Powell

@aaronpowell

Hi, my name’s Aaron Powell and I’m a Cloud Developer Advocate (CDA) at Microsoft. My area of specialty is front-end web dev and .NET (especially F#), but I enjoy doing silly things with technology.

Microsoft Azure

Any language. Any platform.

Discussion

pic
Editor guide
 

I created the C# project and ran it successfully. I swapped the .csproj for the .fsproj and the .cs for .fs. I added
to the .fsproj. I pasted your sample code in the .fs. It would not resolve the dependencies, not even with an explicit dotnet restore. Any ideas?

 

Did you include a reference to FSharp.Core in the fsproj file?

Does it output an error messages when you try and restore? Can you share the output of dotnet restore?

 

Yes. dotnet restore says it succeeds. I’ll give it a look tomorrow.

While watching this video youtube.com/watch?v=SSBc5ucHq2E, I noticed that I forgot to include

  <ItemGroup>
    <Compile Include="HttpTrigger.fs" />
  </ItemGroup>

in my .fsproj file.

Ah yes, you need to explicitly include all F# files in the fsproj and you need to include them in the order you want them loaded by the compiler (since a file can only access what's been loaded prior to it).

It’s funny because I knew that, but I guess I’ve never translated a csproj to an fsproj by hand, so it’s never come up. Thanks!

 

Don't forget to pin your Fsharp.Core Version as only 4.2.3(Nuget Version the contained Fsharp.Core Version is 4.4.1.0) is supported currently. I have created a PR to update it to a more current version here.
Also have a look at this article written about this issue here

 

Good to know! I haven't deployed mine yet, only run it locally (still very much in the dev phase 😉) so I hadn't hit that error.