Mithun Shanbhag

(blog | rss | twitter | linkedin)


Quick links

my old blog

my speaking engagements

awesome azure resources

awesome azure devops resources

Why we're not moving our web APIs to azure functions yet

Published on 18 Feb 2019 by Mithun Shanbhag

I’m a big proponent of azure functions, having used it on a daily basis for over a year now (for both work and personal projects). The cost savings have been enormous, especially with the consumption plan.

As you probably know, azure functions can be classified into three groups: timer-triggered, data-triggered and http-triggered.

However, today I want to talk about why we haven’t converted our core web APIs to http-triggered azure functions. What’s stopping us?

1. No SLA/guarantees around cold start latency

In our anecdotal observations, for the consumption plan, we’ve seen cold start latencies exceeding 45 seconds at times.

Since we’re talking about the consumption plan, there is no “always on” option for these function apps (and rightfully so). Yes, it is possible to resort to workarounds to keep the function app warm (by calling it every ‘x’ minutes from an external app). But this is unnecessarily tedious.

Note: This blog post is the only “official” documentation that we could find around cold start latencies in azure functions (it’s a well written, detailed blog post).

2. Azure functions v2.x don’t yet support OpenAPI / swagger

We use azure API management (API gateway) as a “front-door” to our Web APIs. Since v2.x azure functions don’t yet support OpenAPI / swagger, it is not possible to import them into the azure API management (related twitter thread.

You’ll have to generate the openAPI definitions either manually or using external tools (swagger inspector, postman etc) which again is a tedious process. Currently, it is not possible to use swashbuckle with azure functions either.

FWIW - The azure functions team has been aware of this issue for a while. Hopefully, they’ll add this support in their coming sprints.

3. Lack of dependency injection services (IoC container)

Yes, a whole slew of input bindings exist for azure functions. However it is not possible to inject custom dependencies (a la A DI service support would have been really useful for instantiating entity framework dbContexts, auto-mapper profiles etc (related twitter thread).

Currently, the “recommended” approach is to use statics to cache these dependency objects, but what we really want is a mechanism for creating & passing around ephemeral/transient dependencies.

4. Lack of a middleware mechanism

Would have been really nice to have a lightweight middleware (say) to process JWT tokens across all http-triggered functions in a function app. Instead we now have to explicitly invoke helper methods from each http-triggered function.

5. No POCO model binding support

Edit: I stand corrected. Looks like binding to POCOs is indeed supported as shown in this example. More details here and here.

Azure functions do not support POCOs during request/response model binding. All types must be serialized to one of the following: string, binary or stream. You can choose to author a custom binding as a workaround for this issue (which again is tedious).

Technically speaking, there is nothing preventing us from transitioning our web APIs to azure functions. We simply have to work around the above-mentioned issues (which are nitpicks really). However since our web APIs are still nascent & evolving, this transition will require us to sacrifice some developer productivity (e.g. the OpenAPI support issue).

So for the foreseeable future, we’ll be sticking with core + azure web apps to host our web APIs. But really hoping the azure functions team addresses the above-mentioned issues, so we can go ‘truly’ serverless.

Comments? Suggestions? Thoughts? Would love to hear from you, please leave a comment below or send me a tweet.