Public API on Azure

Eric Huang
5 min readNov 9, 2016

--

Currently, I am working on an interesting project exploring the Azure API Management. The idea is to have a proxy or gateway API in front of a API (called Backend API which is a term used in Azure) you develop. By adding this extra layer and abstraction, Azure is able to offer extra nice out-of-box and configurable features, such as caching, authentication, rate limiting, etc so that our Backend APIs can focus on solving the domain problems. You can think of this extra layer as an application of Aspect Oriented Programming.

In this post, I am going to talk about what API Management offers, what additional operational concerns are, and a few deployment tips.

Overview

Based my experience with building Public APIs and Microservices, putting Public APIs behind this Azure API Management seems a perfect use case since it just does what Public APIs need.

Secure Backend APIs

It hides your Backend APIs from public. No matter whether you are deploying APIs using IaaS or PaaS, you can always deploy your APIs into a VNET (see a new PaaS feature) to securely host internet inaccessible APIs, and then connect proxy to your Backend APIs via VPN. Alternatively, a client certificate approach can be used to authenticate proxy and Backend APIs to avoid a man-in-the-middle attack.

Reduce development effort

Once you’ve defined your first proxy, lots of nice out-of-box and configurable features become available without any code, such as rate limiting, caching, retry, response customisation, etc. You still need to develop Public APIs but all it does may just aggregate result from the clients/consumers’ perspective (because it is designed to be clients/consumers oriented).

Operation concerns

When using Azure API Management, essentially an additional component is added into the request processing pipeline. The clients or consumers do not talk to your Backend APIs, instead, they talk to the proxy. With the extra component (the proxy) being added, what do we need to do to maintain quality of the service from DevOps’s perspective? There are a few situations that may affect the quality of service. How to react to those situations depends on the responsibility. Let us look at those situations individually.

A component has outage or be inaccessible (infrastructure issues)

  • If you have control over the infrastructure used by the component (for example, you use IaaS to deploy your APIs), it is your responsibility to make sure it can be accessible. One way to achieve it is to have a health check endpoint, ping every instance of its deployment every X seconds, and trigger alerts if it is down. AWS is a good example using this approach to check if an EC2 instance should be in a ELB. Regarding the health check endpoint, see a pattern and blog.
  • Otherwise (for instance, you use a PaaS solution, like Azure API Management), you do not need to worry about the underlying managed infrastructure. However, you want to get notified when the service goes down. Azure Status is a place to know the services availability, or you can set up a pinger to ping the component using tools like New Relic (Thanks Clancy for mentioning this New Relic feature).

A component has unhandled exceptions (code issues)

  • If you have control over the component (like your Backend APIs). It is your responsibility to log them and get your notified. You can DIY, or integrate with tools like Loggly, Sumo Logic, etc.
  • Otherwise (like Azure API Management), you do not need to worry about (or may not able to access to) those exceptions.

A component has performance issue

If clients or consumers experience performance issues, you want to be able to easily find out which components cause the issue. In order to do that, every component in the pipeline needs to provide performance insights about what is going on and offer ability to set up alerts if the performance is not acceptable.

  • If you have control over the component (like your Backend APIs), you can either DIY or integrate it with APM tools like New Relic
  • Otherwise (like Azure API Management), you use the features provided. At the moment, Azure API Management has no way to set up alerts which I think is a must-to-have feature in terms of monitoring. A workaround to it is to log every request’s response time to Event Hub, and have a Event Hub receiver to process the log and see if the response time is acceptable.

Deployment

Naming

It would be great if there is a convention around how to name proxy and Backend API so that it is easy for developers and operations to find where the services are. For example,

  • Backend API URL is memberaccount-api.azurewebsites.net
  • Proxy URL is memberaccount-api.portal.azure-api.net that redirect requests to the Backend API
  • Set up a CNAME memberaccount-api.energy.com.au which points to the Proxy URL

Creation of proxy

Ideally, when a proxy is deployed, only DNS changes is required when switching traffics to proxy. There are a few ways to create a proxy.

One proxy per One Backend API.

Pros: Simple. Great isolation

Cons: Set up and manage same number of proxy as the number of Backend APIs. Operational costs (like monitoring / alerts) may go up

One proxy for Multiple Backend APIs

Pros: Operational costs (like monitoring / alerts) are reduced

Although it is not difficult to implement as proxy is able to specify Backend API to be used using a policy, this approach has a few concerns to consider

  • Complexity. The proxy needs to figure out which Backend API to use, it means customised logic needs to be defined in proxy. It may make proxy heavy and tightly coupled to vendor’s features. Alternatively, this can be fixed by introducing a new API where has those logic, however, you still need to solve the issues below.
  • Lack of Separation. The changes to one of Backend APIs need a deployment to the proxy which may affect other APIs (which have no changes, then should be no deployment) co-hosted within this proxy. This is like you have multiple deployable applications in a single repository in which case it is hard to figure out which application needs a deployment when a single changeset is made to the repository.
  • URL or version conflicts. If a same path is supported by Backend APIs (like /myaccount is supported by api1.energy.com.au and api2.energy.com.au), changes must be made to existing code to have different path so that proxy can figure out which Backend API to use. Speaking of versioning, check out the new ASP.NET API Versioning.

Personally I would prefer the first approach because it looks like the second approach may have more problems.

Azure API Management is definitely a very interesting service that can help build Public APIs.

--

--

Eric Huang

Passionate Technologist and Continuous Improvement Practitioner