Skyler Hartle is on the Azure Functions team and focuses on APIs, growth hacking, and other neat things.
*record scratch*
*freeze frame*
Yup, that's me. You're probably wondering how a former JavaScript developer ended up using Azure Functions for all his API-related projects.
Before I joined Microsoft, I spent most of my days developing API-related applications using Node.js, or more specifically, I leveraged the MERN stack (MongoDB, Express, React, and Node) to create different applications, back when that was still the hotness.
Like many of us, I gravitated towards the simplicity provided by something like Node.js + Express together. It just worked. And it was fast to get started. Easy to spin up new projects and services as needed. As time progressed, I eventually gravitated towards the next shiny thing -- JAMstack (JavaScript, APIs, Markdown) -- because of a similar allure; discrete layers, speed, ease of use, and an appealing mental model for developing new applications that made sense to me.
The technologies involved all had a similar theme:
After I joined Microsoft (and subsequently joining the Azure Functions team), I discovered a spooky truth. Many, many people were using serverless platforms, like Azure Functions, for their API-related applications. It turns out that building APIs is one of the most popular use cases for Azure Functions-- for good reasons.
I immediately began investigating what this meant for somebody like myself, a developer with a strong passion for APIs and good API development and API design, and this is what I discovered along the way.
Why developing APIs with Azure Functions is a good great the best thing
The programming model for Azure Functions requires that you create small, single units of compute that are perfect for routes in an API. If you're coming from a background using other frameworks, such as ASP.NET, Django, Flask, Express, Koa, etc, you're already familiar with an application model that has an opinionated way of creating routes for your API. The jump from this mental model to using something like Azure Functions is not difficult and is more of an evolution of this existing way of doing things than a complete divergence.
If you aren't familiar with Azure Functions, here's a quick overview:
- Azure Functions is a "functions-as-a-service" platform, allowing you to run code in the cloud without managing servers.
- In Azure Functions, you create function apps.
- Inside a function app, you have a series of functions.
- Inside those functions, that's where your code lives.
- Thus, a function app is just a collection of functions, with each function containing a bit of code, and that's it!
Much in the same way that a framework such as Flask (for Python) or Express (for Node) might generate scaffolding code and files for you, Azure Functions just goes one step further by providing the scaffolding and the hosting environment to run your API.
Here's an example of how you might use Azure Functions to create an API:
- You create a function app (a grouping of multiple functions) called "UserAPI".
- Inside this function app, you create four functions, each of which responds to an HTTP request in a different way: GetUser, CreateUser, ModifyUser, DeleteUser.
- Write the business logic inside each individual function, corresponding to each specific route.
- A new URL is generated per function (not per function app!), that you can direct specific requests towards, such as GET, POST, PATCH, and DELETE requests. For example, a GET request may be directed towards GetUser, POST requests towards CreateUser, PATCH requests towards ModifyUser, and DELETE requests directed towards DeleteUser.
Each function is self-contained, allowing you to modify the business logic within the function, add additional dependencies to the function, without polluting the scope of the other routes, or introducing unnecessary complexity elsewhere in the global scope of your application.
The business logic for each function may differ, but the way you create a new function is the same.
The image below reflects the same function app structure as outlined in the numbered steps above.
To sum up why all of this is a good thing:
- A function is a discrete unit of compute, encapsulated and living within its own context. This allows you to pull in only the dependencies you need, for the exact logic you're trying to run.
- Spinning up a new function via VS Code is without a doubt the fastest way to create a new, external API, compared to other methods such as virtual machines.
- Azure Functions provides not only ready-made scaffolding for writing an API, but all the necessary hosting.
- Serverless models enable consumption-based pricing which means you pay nothing when there is no traffic hitting against your API.
- When there is massive traffic hitting your API, functions will automatically scale with respect to demand, ensuring no outages for this often critical layer of your application infrastructure.
The 'Hello, world' tutorial, HTTP endpoint style
If you want to test out Azure Functions for yourself, you can follow the very (overly) simple instructions below to try this for yourself, in only four steps. The simplified tutorial below will provision a new function app for you, with a single function, exposed to the world as an HTTP endpoint.
- Prerequisite: install the Azure Functions VS Code extension.
- Once installed, open the Azure Functions extension and click 'Create New Project', select a folder for your project.
- When prompted, select 'HTTP trigger' as your template and hit enter a few times (don't worry about those pesky details).
- Click 'Deploy to Function App’.
- Once the deployment has finished, you can browse into the resource group, find the function, and right click to copy the newly created function URL.
- Throw that thing into your favorite browser, and see the results!
'Create New Project' button, on the Azure Functions extension.
'Deploy to Function App' button, on the Azure Functions extension.
Find the URL for your newly deployed function.
The above example is just a quick intro, but it works! Your application can't do anything meaningful, but if you want to do more with the function app you just created, the structure is in place for you to add business logic to your API now with minimal effort.
If you want a more comprehensive tutorial, you can read our quickstarts to learn how to do this in a variety of different environments.
Generating a function app from OpenAPI specifications
Let's crank this sucker up to 11.
If you're already in-the-know with APIs, it's likely you're either using or at least familiar with OpenAPI specifications (Swagger). OpenAPI specifications are machine-readable documents that describe RESTful API services, which has a number of useful purposes.
There are two main schools of thoughts on when/how to use OpenAPI specifications:
- Code-first, where you develop an API, and then generate a file such as an OpenAPI specification, or...
- Design-first, where you write a document, such as an OpenAPI specification, that describes the intended functionality of the API.
More recently, design-first API development has been getting attention, especially when leveraging a descriptive document such as an OpenAPI specification. This document effectively becomes a contract; teams of people can develop against an agreed upon OpenAPI specification, knowing that this document reflects the truth of the API. An OpenAPI specification serves as the contract, documentation, and source of truth for the API, making it a great way to plan out an API for a service.
To support the design use case, we recently released an update to our Azure Functions VS Code extension that lets you generate a function app from an OpenAPI specification. This is a brand new feature (in preview), with support for TypeScript, Python, Java, and C#. JavaScript and PowerShell coming soon!
For developers familiar with something like Flask or Express, this functionality basically creates all of the scaffolding necessary to get started building an API, similar to how you might use one of the aforementioned frameworks. It goes beyond that, too, inferring important route information from your OpenAPI specification and automatically generating route-related details within your function for things like parameters. You can check out the GitHub repo for more documentation, or go through this simplified quickstart:
To check this out, all you need to do is:
- Prerequisite: Make sure you have the latest version of the Azure Functions VS Code extension installed.
- Prerequisite: You’ll also need the correct language runtimes installed for the type of function app you want to create.
- Prerequisite: Install AutoRest, which is used as a dependency by the plugin.
- Create a new function app and choose the 'HTTP trigger(s) from OpenAPI V2/V3 Specification'.
- Choose your language of choice (TypeScript, Python, C#, or Java).
- Select your OpenAPI specification, and boom! Magic starts to happen!
To see the magic happening, the following gif steps you through this process for a Python app, and shows the end result:
A complementary functionality is also (coming soon) in the Azure API Management VS Code extension, wherein you will be able to generate a function app from an existing API you are managing within API Management. If you’re interested in learning more about how you can explore Azure Functions and Azure API Management together, we recently published a new workshop on Serverless APIs on GitHub.
We also support the ability to do this from CLI commands, as well, as shown in the example below:
autorest --azure-functions-typescript
--input-file:C:\\path\\to\\spec.json
--output-folder:./generated-azfunctions
--version:3.0.6314
--no-namespace-folders:true
For more examples of this, refer back to the GitHub repository for this new feature.
Wrapping this thing up
For those of you who work extensively on API-related use cases and are considering making the switch, I highly recommend examining the value that something like Azure Functions can bring to your development process (and the improvements to your quality of life). I’m a paid shill for Azure Functions, so of course, take what I say with a grain of salt, but as a lifelong developer and lover of technology, I would never advocate for something I didn’t believe in.
Let us know how we can make Functions better for you. Tweet us @azurefunctions, or you can send me a message, @skylerhartle, on Twitter, if you want to chat.
Top comments (8)
Hey Skylar, great read!
I've been wondering though (after dabbling myself), it seems Azure Functions would have a hard time responding quickly to requests (due to cooling/warming). Any advice on that matter? How would Functions beat a good old django app run on a web app?
I have been wondering this also. I wonder if @skylerhartle knows anything else on this?
Hey Skyler, This is great! I have been wondering for a while which way to build API's as a noob, and this gives me a bit more context on how to go spec first - thank you.
One thing I've been having issues with Azure Functions is how to authenticate users to them via Azure B2C as part of an app (I'm using React). Are there any resources you recommend?
The walkthroughs/tutorials offered by Microsoft really don't cut it as they are really really fragmented and are very 'here's a bunch of steps' rather than 'here's the gist of what you need to do, why you need to do it, and then how we do it'.
The rapidly evolving nature of Azure Functions seems to be against it as documentation is going out of date very quickly.
Hey Liam!
No kidding re: the evolving nature of Functions. It's hard to keep up with the constant changes, but we're trying to do our best. Have you looked into using the consumption tier for Azure API Management to do this? It's the path we recommend for API related workloads:
Secure an Azure API Management API with Azure AD B2C
APIM supports AAD B2C out of the box. You essentially will throw a proxy in front of your Function via APIM, and then leverage the capabilities APIM provides. You can link/create a new APIM instance via the Azure Functions portal blade (it's under "API Management"), which would be the fastest way to spin up a new API that's linked to your function app.
I understand it may seem counterintuitive to spin up a new service for a single feature, but IMO, using API Management for throttling, authentication/authorization, etc, is a nice way to abstract those details and establish a good foundation for the future.
Would love to hear your thoughts re: if this is overkill for you or not.
Baracuda OpenAPI Azure Functions NET Core 3.1
Generate the json file openAPI 3.0 and the front end view to interact with the API’s calls based on the setting defined in the json file openAPI 3.0.
nuget.org/packages/Barracuda.OpenApi/
chambapatodos.com/
Lovely read!
Excellent article Skyler. Thanks for sharing.
Excellent article. It really helped me as a starting point.