Last weekend, I was experimenting with Azure Functions. This because I’m planning to use Azure Functions for creating a simplified abstraction of an existing web service. The goal is to code and deploy as little as possible by reusing existing modules.
Azure Functions, before we begin
If you are new to Azure functions, I highly recommend reading up on the basics. I’ve actually blogged about this a couple of months ago. You can find this blogpost here: azure-functions-and-logic-apps. Within this post, I’m using Azure Functions in conjunction with Azure Logic Apps. However, Azure Logic Apps can be substituted for any technology that’s able to communicate over HTTP.
Reusing existing code
Let’s first cover what my goals are before we start with implementing the solution.
I want to simplify the usage of an existing third party web service (in this case GTmetrix) by creating a new service with a different abstraction. Before the introduction of Azure Functions, I would have created a new ASP.NET WEB API project. And within this project created routes, controllers, actions, methods, etc.
Now, that’s a lot of work when it comes to very small projects. Fortunately, Azure Functions allows us to glue things together without much effort. however, there are a couple of “gotchas” when you start going this route. I will cover all steps below and include the issues I’ve encountered.
Note: The documentation which is available today covers most of the steps, but doesn’t include any troubleshooting information. I’ve included a link to the resources I’ve used at the end of this blogpost.
The implementation steps
Step 1 – Creating a new Function App
A Function App is a container that hosts Azure Functions. Creating a new Function App using the Azure Management Portal (or API) is simple. Once created, locate and open the Function App within the Portal. A new type of screen should appear at this point.
Step 2 – Creating a new Function
Within the interface select New Function, A new selection screen should show up containing pre-defined templates. For this scenario, I’m using C# as a language and I would like to call my function from an external source. Therefore, I will have to choose the template called Generic Webhook – C#.
Give the function a name and click Create. Not long after that, the screen should display the Develop tab.
Within the code section, I’ve included the code as displayed below. Within this piece code, I’m including two external libraries: Newtonsoft.Json, a well-known 3rd party Nuget package, and GTmetrix-net a Nuget package I’ve created myself.
Note: You can use Environment variables or app setting to avoid hardcoded values. Which I haven’t done to keep everything simple.
Step 3 – Referencing External Assemblies
As mentioned in step 2. I’m making use of two Nuget packages. Using NuGet packages is not required however, making use of NuGet packages makes everything a lot easier.
One thing to note is, is that the assemblies listed below are special cases and may be referenced using a simple name. (e.g. #r ” Newtonsoft.Json”)
After this, you can import the namespace as usual, with the using clause. (e.g. using Newtonsoft.Json”)
Custom Assemblies via Nuget
Using a custom assembly is easy when you have wrapped it into a NuGet package. The process however is somewhat different from Special Assemblies. First, you will need to create a project.json file. You can do this using a tool called Visual Studio Online. To open Visual Studio Online click Function app settings located in the right corner.
Locate Advanced settings at the bottom of the screen and click on Go to App Service Settings.
Within the management blade find the section called Development Tools. And open Visual Studio Online by clicking on App Service Editor, Go.
A new screen will open with the layout of your functions. By default, every function has a run.csx which contains your function code and function.js which contains configuration-specific information.
Within the root level of your function, create a file called project.json. The example below shows how to reference an existing Nuget package.
Note: Only the .NET Framework 4.6 is supported. Therefore, make sure that your project.json file specifies net46 as shown here.
After this, you can import the namespace as usual, with the using clause.
Step 4 – Common issues
I was running into many issues when trying to reference my custom Nuget package. Therefore, I would like to explain how to verify that your Nuget packages are correctly deployed.
First of all makes sure that after saving project.json, a new file called project.lock.json has been created within the same directory. This file contains details used for restoring Nuget packages and should not be altered directly. If it has not been created, make sure that project.json has the correct format.
After saving project.json, your Function App should download and deploy all referenced Nuget package automatically. A pointer to the location can be found within the project.lock.json file. Just search for packageFolders (D:\\home\\data\\Functions\\packages\\nuget in my case). You can open the location via Kudu (Azure Portal console). Just check to see if this process completed correctly.
If you are running into issues with your packages (as I did) I recommend deleting the project.json and project.lock.json file and manually remove the packages from the directory. After this, just simply recreate the project.json file.
Step 5 – Calling the function
There are two ways to test your function. The easiest way is to use the Run option located on the Develop tab. Just make sure to provide the correct input values within the Request body input box.
The second way is to actually call you function using the generated webhook aka Function Url. You can use a tool like Postman to create a simple POST request.
Now, it’s unlikely that someone would be able to correctly guess your Function Url code however for real scenarios it’s recommended to include some form of authentication.
I’ve only covered a small part of Azure functions, there is so much more to cover. I hope this post demonstrates how easy it is to reuse existing modules within your Functions. And in addition to this also shows how simple it is to create a webhook function.