Sunday, August 27, 2017

Maybe the most useful Azure function ever! – Introducing a proper Swagger definition generator

This post relates to Azure functions written in C#, hosted as a Function App – and maybe the title is a tiny bit clickbaity ;)

I’m in a project where writing small Azure functions to accomplish pieces of functionality is a very good fit, and the tasks will be connected in a workflow – Microsoft Flow or Logic Apps. With the latest update for Visual Studio 2017, creating an Azure Function project and publish the function to Azure is super easy.

The tricky part comes when you want to consume those functions somewhere else using a Swagger definition file to describe your API.

The people over at the Azure team has been kind enough to add functionality to automatically generate a Swagger definition. The problem is that the output of this preview functionality is, to put it in nice terms, the equivalent to a table of contents, where the book was left out.

image

There are some blog posts out there on how you can write that book to get a working definition, but manual work when you have already defined the functions pretty well in code is not my cup of tea.

Digression

If an Azure function project had been a WebAPI or similar, you could have installed Swashbuckle, and you would have gotten a nice Swagger definition just like that. The fact that Azure functions are compiled to a class DLL, and that Swashbuckle does not work against a DLL in any easy fashion, I saw two options. A shadow API with Swashbuckle, or roll my own.

I started out with the first option where I created a shadow WebAPI project, copying all my Azure Function signatures, and then manually copying out parts to generate a proper Swagger definition. But I quickly discovered this was still too much manual work for my taste.

Option two it is – generate the mofo myself!

That left me with option two, write my own Swagger generator. The Swagger spec itself is not too complicated, and as Azure uses v2, that’s what I set to use as well. I’m no stranger to reflection on .Net DLL’s, having worked with SharePoint for many years, as well as writing other types of generators, so that’s what I did.

I created an Azure function in my project which at run time reflects on the current assembly, finds all methods marked to be Azure functions, then inspect their ins and outs, and construct a full fledged Swagger definition.

It’s not complicated, but a bit tedious to support all the scenarios I wanted to support. I wanted to support input via the path, as query parameters and JSON objects in the body – which is the most useful one in my opinion. It took me one working day, 7.5h to have this up and ready to go, with ~400 lines of code. Imagine if the Azure team could have spend the same? But then again, I wouldn’t have this blog post :)

The code and things to be aware of

You can get the code at https://github.com/wobba/AzureFunction-SwaggerDefinition
  • Copy the Swagger.cs file into your project to get going.
  • You need to add a reference to System.ComponentModel.DataAnnotations, as I use the Display attribute to reflect out the summary and description of the functions – needed for Microsoft flow.
  • See the sample functions in Templates.cs to get an idea on how you can craft and annotate your functions in regards to input and output values.
  • Nested complex types works fine, but not sure if Microsoft Flow support them.
  • The default function to get the Swagger definition will run on /api/Swagger.
  • Microsoft Flow works best with defined input and output objects, not using simple types.

How to use with Microsoft Flow

Once you have published your functions to Azure, navigate to the Azure management portal and your function app. To ensure easy import of Swagger from Azure Functions to Flow, disable CORS on the function app by allowing all domains with a *.



Next get the default API key and make a note of this as you will need it later. The API key can be retrieved from the Function App Settings page.

imageimage

Get the Swagger definition URL by clicking the Swagger function and Get function URL.

image

Go to the Platform features tab and click API definition. On this page you could click the X’ed out Function button and get an auto generated swagger table of contents, but as we want the full book, hit Set external definition URL instead, and point it to your custom Swagger definition function URL from above.

Note: Another option is to create a custom connector directly from Flow, using the same Swagger URL.

image

Once the URL is pasted into the API definition location input box, click Export to PowerApps + Microsoft Flow. Fill in the appropriate information, and paste in the Azure function API key (which you made a note of earlier) in the API Key Name field.

image

When you click OK, and everything went according to plan, you should now see your Azure functions show up as a custom connector in Microsoft Flow.

image

Next up edit the custom connector and add a label for the API Key parameter as seen below. You can also change the icon, name, function names and descriptions etc. if you want.

image

Now it’s time to test the API. At the Test tab you can create a new connection (if you try to consume the API in Flow before adding a connection here it fails the last time I tried).

image

Use the same API Key you used when exporting from Azure to PowerApps + Flow. In theory I would have thought the connection was auto-made on the export – so maybe something went wrong and this step might not be needed. Easy to tell if you see a connection already on the Test tab.

image

Test it all in Microsoft Flow

Once you have tested your functions, head over to Microsoft Flow, find your functions and hopefully it’s all working with green lights on all steps. You should also be able to see defined inputs and outputs for each action.
image

Fill in data, save and run the flow.

image

If all went according to plan, you should see an ok checkmark for both steps.

image