Zach Olivare - 2020 Jul 13
But after hours spent sorting through the confusing, incomplete assortment of Microsoft documentation on the topic, I did manage to produce some nice functions and gain an understanding of the various aspects of Azure Functions.
In this post, I hope to help your getting started experience move along faster than mine did.
Jamstack is growing in popularity, and for good reason! Jamstack sites are serverless. Instead of storing source files on a dedicated server, the source files are instead served over a CDN for better (potentially global) performance.
But if there's no server, then how do you interact with a database or any other backend service? That's where Azure Functions (or something like it) comes in.
The idea behind Azure Functions is to have a blob of code that you can push to the cloud, without having to worry about ecosystem in which it runs. You don't have to create (for example) an express server and then figure out how to publish and run that server in the cloud. Instead, you just give Azure a blob of code and set some configuration options about when that code is run.
There are 4 pieces that make up an Azure Function, as illustrated well by the Azure Portal:
The function trigger is the condition that tells the function to run. Azure supports a wide variety of triggers; additions or mutations of Blob Storage, a change to a Cosmos DB, and an HTTP request to name a few.
The trigger is passed as the second argument to your function, the first being the context object.
For HTTP triggers for example, the HTTP request object will be passed.
Inputs are passed as arguments to your function. The first input will be the third argument, the first being the context object and the second being the trigger.
There are other ways to access the inputs too.
One confusing thing about the function is the first argument that's always passed to it, the
The context is basically just an object jam-packed with everything that Microsoft wants to give your function access to.
For example you can call
context.log() to write trace output to the console. You can also call
The context is also where you'll access the bindings you've configured via
context.bindings. HTTP request triggers and HTTP response outputs are so common, that in addition to being able to access theme via
context.bindings.res respectively, they also exist directly on the context object as
context.res. That's in addition to the
req being injected as the second argument to your function. They give you plenty of rope to hang yourself with here, but just pick your favorite and be consistent.
Outputs are the side effects that your function produces, like creating or updating an entry in your database.
A binding is basically a way of interacting with some other system that Microsoft has baked into the Azure function for you. But because you have access to NPM packages (I talk about how to install them below), you're not limited to just those bindings.
Before I talk about how to get started, I wanted to clarify something that confused me initially.
Your goal is to set up a Functions project (the Azure portal calls it a Function App), not a singular function. So if you use the portal to create a Function, you're creating one Function inside of a Functions project. If you use an IDE, you're creating the structure of the project first and then individual functions inside of that project.
It's possible to develop Azure Functions without ever leaving the Azure portal. But it sucks. Their online code editor is frustrating for even the simplest of changes, and while using the portal it's not possible to also use any NPM library.
Additionally, and perhaps most importantly, writing your Functions in the portal prevents you from storing them in version control! One accidental click and all the work you've done can be deleted.
Using the portal can be a nice way to just write something up there and see it run quick, but even for that use case I think you would be better off...
VS Code has an Azure Functions extension that is incredibly easy to use and makes the whole process of setting up a Functions project much easier.
I would suggest just following the steps laid out on the extension's home page. They walk you through creating a project and creating your first Function. Keep in mind that if you've messed around on the portal, you can use the Function project that you've already created to save on paying for additional resources.
One other area you might deviate from their walkthough is in how you run your Function project locally. They suggest using the integrated VS Code debugger. You can definitely do that if you want to, but I prefer running scripts in my own terminal outside of VS Code.
To do so, from the root of the project run
npm start in your terminal. This does the same thing that the VS Code integrated debugger would do; using the pre-installed
@azure/functions NPM package to watch your code and restart the server when you make changes.
You can bolster the power of Azure Functions by installing and using libraries from NPM.
Doing so is as simple as running
npm install in the root of the project (as you would expect) and then
importing them exactly as you normally would.
When you deploy your functions to azure, your
node_modules directory will be deployed as well so that everything continues to run the same once deployed as it ran locally.
This choice is largely preference based, but I feel that TypeScript has two big advantages here:
module.exportssyntax, which I strongly prefer.
The only disadvantage that I've found is that sourcemaps don't see seem to work, so your errors don't point to your original source code, but it's generally pretty easy to figure that out for yourself.
On the whole, I found Microsoft's documentation around Azure Functions rather confusing and disappointing. Perhaps they do have some great docs somewhere, but it's really hard to find the one you're looking for when you're not sure what that is.
If you're looking for more information on how to work with the Gremlin API of Cosmos DB, please take a look at my next blog post in this series; How to Manipulate a Gremlin Cosmos DB From Inside a Node.js Azure Function.