APIs are great. Saying that your SaaS application ought to have one is pretty uncontroversial. Suggesting that any end-user interfaces your SaaS app provides should be built on top of your own API isn't all that controversial anymore either. I'm sure there are exceptions, but let's take those arguments as made and move on to the idea of creating automatically-generated SDKs as a value-added layer on top of an existing API.
I certainly didn't come up with this concept—my former employer Pluck had been doing this since 2010 or so (brief introduction here)—and a new service called APIMATIC has taken it further by providing automatic generation for any API. However, I can share some firsthand experiences with the benefits and downsides of SDKs. They are a relatively inexpensive way to get an edge on your competitors (or keep up with them, if they already have SDKs); they are not all unicorns and rainbows.
That said, as long as you do a careful cost/benefit analysis, this technique is absolutely worth considering.
First, a brief tutorial of how you can roll your own. (If you're already clear on the details of and differences between an API and an SDK, you may want to skip down a bit.)
A quick description of web service APIs
To perform something similar using web services, you pass the data to a given endpoint (URL) and get the result back. The only thing being transmitted is a set of values—ergo, a bag of properties. Since there are only values and no logic, there's not any meaningful encapsulation to speak of.
Methods are highly language-specific, properties far less so. (Every language has integers and strings and such; the language-to-language syntax variation is far easier to overcome than the logic statements that make the methods do stuff.) The fact that only properties are being shipped across the wire means converting them to and from any language-specific SDK is pretty easy.
The difference between an API and an SDK
The property bag items shipped from your server across the wire to the client program are just strings. To utilize the numbers coming back from our purchase cost calculator, that string has to be parsed into an actual number. (Doing math on strings is generally not so successful.) Similarly, a more robust API call might return complex structured data that then needs to be parsed into something the client's native language can work with.
The SDK is the thing that does all this parsing. (Technically, it handles serialization and deserialization.) APIs are raw; the SDK's job is to make programming against those APIs much easier. (More about the advantages and disadvantages of SDKs a bit later.) Think of SDKs as a layer sitting atop the API.
The Robot Factory
(By which I mean a factory staffed with robots, not one that makes them.)
Creating a single SDK language for your API is pretty useless unless all of your customers are using that specific language, so to address the whole market you might need a half-dozen SDKs or more. Manually creating even one is expensive when you have a fairly robust API, so the cost of 6 is prohibitively high. So what to do?
Again, since the API is just receiving and shipping strings, all an SDK really needs in order to handle responses is to translate (deserialize) those strings into native objects using language-specific data types. Making a request reverses the process: client programmers will create native data structures and the SDK will translate those into what the API endpoint needs. This serialization/deserialization facility is the core requirement for a web services SDK.
Depending on how nice you want to be, there may be a little more to it than that. Some possible language-specific parts of an SDKs include:
- the transport mechanism (helpers that handle the sometimes-arduous process of making an HTTP call and receiving the result)
- helper functions for handling your API's error conditions
- unit tests
- idiosyncratic documentation formats (JavaDoc, for instance)
You may choose to leave some or all of that out of your SDK, making it the client programmer's job to find or build those tools (and there are good reasons to do so)—but the point is that apart from these pieces, all you need is a simple templating system to generate the language-specific property bags, and the serialization & deserialization facility, from your underlying API.
Here's what the robots do
The robots in this case are just a series of templates that translate metadata defining your API into language-specific objects. Take this example:
Here we see a human representation of a development estimate record accepted by or returned from an API. The metadata describing that object is passed into a couple of translation templates that simply spit out the code in C# and Objective-C. (This could be handled by Django templates, Velocity macros, or anything of that ilk.) The template itself only needs to know that the task name is a string and the hours estimated is a number (etc.); it can then write out native objects that use native data types.
The great news is that these templates, as well as the serialization/deserialization layer, need only be written once per language. It's also pretty easy stuff (read: inexpensive). Even better, it scales well (near "constant complexity" in programmer terms, which means "cheap at scale"). Generating an SDK from an API with 1,000 data objects and 100 calls costs pretty much the exact same amount as one for a simpler API with 10 data objects and 3 calls. This cheap scaling is vital as your business and your functionality grow.
Aside: Even the API itself can be automatically generated from the underlying system that runs it. Take for example a big Java system that you want to build an API from; the metadata I mentioned earlier can come from Java Annotations in the core system's code. This would then generate the API and the SDKs. (The equivalent markup in .Net is called Attributes.)
The competitive advantage, and its downside
The Programmable Web article I referenced earlier has a great little description of the pros and cons of SDKs built this way. (Scroll down to "When to Use SDKs?")
Here's my summary:
SDKs provide some immediate benefits to the client programmer:
- Native language code is far easier to understand and code against when you're new to a SaaS system you're trying to integrate with. Simply put, it's cheaper for your clients to get started using your API. Cheaper is good.
- Typed languages provide tremendous safety by catching mistakes at compile time (rather than after the system is running). This means an SDK in a native language is also easier (cheaper) in the long run by virtue of its preventing pernicious errors. Cheaper is good.
- As you grow and improve your API, new versions of your auto-generated SDKs will expose new functionality "for free".
That last point is a great segue into…
- New versions of SDKs mean a cycle of re-implementation and re-testing for your customers. While conceivably it won't be necessary to change or re-test an implementation if it isn't using a part of the SDK that's been modified, many customers (including almost all big enterprises) will insist on a complete regression and/or won't upgrade out of fear of breakage. This is a real challenge to the core value prop of SaaS—running multiple versions of code in production undermines the fact that it's supposed to be a single service.
- New versions of mobile SDKs pose even greater problems because of how app stores work. When a client programmer needs to swap out versions of your Objective-C SDK in an iOS app (due to a bug fix, maybe), they'll have to resubmit the application and wait for every user to update their installation.
This last objection can be somewhat addressed by segmenting the SDKs into a core of essential parts, and elective modules for less-frequently-used functionality. In this way you could let the client developer download only what they need with no bloat from stuff they're not interested in.
The sum of these objections is why people say that SDKs are a great way to get started but that you should switch to naked API calls (a.k.a. "format your own damn HTTP requests") before going to production. I'm not entirely sympathetic to this argument—you can't reflexively say that's the best way without carefully thinking through the long term gain and pain—but it is an approach to consider and a tactic which lots of programmers undoubtedly employ.
Finding the ROI
I consider SDK generation to be pretty easy programming, but it's certainly not free. The initial engineering investment per SDK is not particularly high in the grand scheme of things, and fortunately there's no infrastructure (apart from the machine that will do the generation, which could just be an old laptop). The initial round of QA definitely adds some expense, as will documentation, but if you can amortize the total development time across years, these costs shouldn't be prohibitive.
However, like all technical debt, you have to keep an eye on the long-term maintenance costs. I see three main areas of concern:
- Keeping up with changes to SDK languages & shared libraries
- Support: there will be bugs to fix as well as red herrings on the customer end to diagnose
- Regression testing when changes are made to the underlying API (or language-specific parts of an SDK)—automate early and often!
The tougher part is estimating the impact SDKs will have on the top line. What percentage of a sale or renewal do you attribute to your SDKs when the deal was influenced by them? This is really tough to gather data on in advance, so customer interviews are essential, and in the end your calculations will be a bit speculative.
To SDK or not to SDK?
The costs have to be more than offset by the additional revenue you can attribute to having SDKs in your competitive toolkit. Getting to the numbers is tricky, but the decision is simple: if revenue is likely to exceed cost across whatever time makes sense for your business, build SDKs.
If you're a programmer, would you rather use a generic API or an SDK? If you're a PdM, which would you rather build and why? Leave a comment below!