How to build a SaaS API

The proliferation of SaaS startups I refer to is largely possible as a result of software developers having figured out APIs (Application Programming Interfaces). APIs have allowed SaaS vendors to independently design, build and release software that plays well together when integrated. While there's a lot left to be desired in the overall ecosystem, it's easy to see how this could have been far messier than it currently is. In this post, I’ll cover some essential considerations for those starting to build their APIs. I’ll cover API and SDK management separately.

Start with REST

Over the years, we’ve seen various attempts to standardize remote APIs - SOAP, <my favorite markup language>OverHttp, gRPC, GraphQL, REST etc. It is safe to say at this point that REST is the most broadly adopted standard that allows extensibility to more modern paradigms like GraphQL and gRPC.

In addition to it emerging as a standard, there’s lots of good reasons why REST is the right option to start with for a wide class of problems.

  1. Most modern web frameworks allow you to design REST APIs without foot gunning yourself. Eg Flask, Ruby on Rails.

  2. There are excellent examples out there of how to build good REST APIs. Sometimes, it’s best to mimic your favorite API. I recommend looking at the Stripe API docs (V2 Blog) that really gets several things right.

  3. If you're hosting your API on the cloud, most cloud providers have first class operational support for REST API, allowing cleaner monitoring, gatekeeping and authentication.

  4. I’ll talk about this in a separate post, but an SDK that allows integrating your software into the developer’s application is going to drastically improve onboarding experience. REST will help avoid having to handcraft all your SDKs and instead autogenerate your clients as you evolve your APIs.

When to not use REST?

While the answer is almost never, there are a few cases where idiomatic REST can come in the way.

  1. For a class of applications that involve a “chatty” protocol that requires a lot of back and forth between client and server, idiomatic REST may not be well suited. Eg: An API that provides clients direct access to a database. Cloud Firestore recommends using their gRPC API over their REST API.

  2. While this is a contentious opinion, modeling problems that are inherently sequential flows as REST resources can seem contrived. The anti-pattern results in each step in the flow being a PUT on the same resource (sacrificing immutability), or each step artificially represented as an entirely new resource (sacrificing cohesion). In such cases, you’re better off modeling the API as procedural instructions as you would in a programming language. Eg OAuth flows are a good mix of procedural and REST.

  3. Similar to the first point, a certain class of problems are most efficiently solved through bi directional streaming, since a request response paradigm may lead to inefficiencies. For such problems, gRPC and GraphQL are the most popular choices.

  4. For APIs that are prone to Spam, there’s an incentive to add to security through obscurity. This happens in large tech companies more often than one might think, where the API can practically only be managed via a client that understands the obscure protocol. While not a true measure of security, anything that makes it sufficiently hard for a novice hacker to reverse engineer your API can dramatically save operational costs. REST may remove such desirable obscurity and not be well suited. 

Ship with an accompanying wrapper SDK 

There’s a lot to consider when writing libraries that I’ll cover in a separate post. But here’s the gist.

  1. APIs should be accompanied by wrapper SDK clients. This saves your customers migration costs and improves onboarding.

  2. Modeling your APIs as restful resources will allow you to auto generate clients for a variety of programming languages. Auto generation can come in the way of API aesthetics, but is typically a reasonable place to start.

  3. API interactions inevitably become stateful, requiring your customers to manage intermediate state on the clients. SDKs save them trouble by allowing you to manage the state for them, and allowing them to interact only with higher level APIs. 

Feature flagging may not be an option

One of the hardest parts of building general purpose software that goes into thousands of applications is the need to get it right early. The costs of a faulty launch are spread across your customer base. SaaS vendors typically resort to feature flagging to help them roll out these changes, and this can be really problematic for customers 

If your changes are an implementation detail that is absolutely invisible to a customer, it can be feature flagged. But this is very rarely the case.

  1. APIs are a contract and customers design their applications around these contracts. If they’re unable to anticipate how the underlying behavior changes as a result of the vendor flagging their features, it leads to a poor developer experience.

  2. While your APIs indicate a certain contract, customers interpret their own contract. Breaking even such implicit contracts leads to an undesirable experience. For example, you could document your API to be an asynchronous long-running operation and design your clients to receive a callback once the operation completes. There’s always going to be customers that notice that your API returns immediately and design their UI to (say) not include a spinner. As the SaaS provider, you’re then burdened with not introducing feature flags that may inadvertently increase request latency, just so that it does not break such implicit contracts.

Alternatives to feature flagging

  1. Publish new features to an alpha channel, where customers can clearly anticipate that things can change unexpectedly.

  2. Having a client wrapper SDK can help make a certain class of feature flags invisible to your customers, by managing rollbacks.

  3. Build a roster of early access partners who are willing to help you roll out features. They’re your new best friends.

  4. Versioned APIs and SDK wrappers can allow you to model your rollbacks as roll forwards. For example, if you want to turn a feature off, publish a new version of the API that does just that. While this is clearly a delayed slow roll back, it is an explicit contract with customers that can be managed better using build tools and IDEs that prompt them to upgrade their APIs.

There’s a lot more I’ll cover in separate posts, but these are the bare minimum considerations you should afford on day 0. Good luck!

Previous
Previous

A pragmatic approach to Semantic Versioning

Next
Next

Building a SaaS startup? Here’s what you should know.