This post is a transcript from Mehdi Raza’s lightning talk at
The Austin Homegrown API Meetup in October 2019.
So, I’m going to talk about what makes an awesome SDK. So who’s got an awesome API here? Hey, nice—a lot of people. So my name is Mehdi Raza. I work at APIMatic. I lead a team there that works on designing SDKs, and designing more generators that work on and create SDKs. And so it’s kind of a bold, big thing that produce documentation, as well. And that lobs it into a portal, as well. So there’s a lot of stuff going on there.
What I want to do is share what we have learned during the last three, four years at APIMatic, designing SDKs for a wide variety of companies. Okay, let’s get started. I’m also known as the CodeGen Wizard at APIMatic.
Who here already writes or provides SDKs for your API? Okay, awesome. Glad to know it.
And so who here has an API that doesn’t have any kind of SDK? Okay.
So if you’re making a grid, you probably want to create a cool delivery experience for the people who are using your product. So if the main way of delivering your product to the people is the API, then the API experience starts mattering a lot. So if you take a payment API, the main way that people are going to be using the work we do, integrating your services.
So if you’re building on top of that, then we make sure that it’s as easy to use as possible, and it’s as frictionless to integrate in your software. So what makes APIs … as integrating APIs into your app as frictionless as possible? That’s where is the biggest element. So I believe that no matter what product you are building, whether it’s exposed to a REST API or through any other kind of mechanism, like you can be using GRPC, or you can be using just an RPC. It doesn’t really matter to the person who was using your product.
API is just a form of delivery for the product.
So it’s just a matter for communication. What they want to do with your product is actually use it, right? So it doesn’t matter whether the calls go through HTTP, or whether they are actually the two software actually on the same computer.
“What matters is what your product does and whether you’re providing a great experience to the developer.”
So if API is just a metric for communication, then basically all API calls for is redundant. But what you’ll see is that people will create great APIs, but they’ll leave SDKs, and translating the call for that API in their programming language to the end user. That’s basically like creating a lot of work for them.
A lot goes into calling an API. You basically have to figure out what portals there are, what goes in a request. For example: the data might go in a query string, the data might go in form parameters, you might have JSON, but all of that is actually irrelevant from the point of a product. The product does something that doesn’t really … the medium of conserve doesn’t really matter when it comes to the product. So that’s why we believe at APIMatic that you must write SDKs for all APIs.
API delivers the product; SDK is the interface.
In a way, API can enrich the product, but the SDK that interprets. So that means whatever API that you are making, the thing that your developers actually want to see is the SDK interface. So you will want to design your SDK in a way that is easy to use, and that it creates a great experience.
You want to make sure that SDKs speak the language of developers.
So if you have an awesome SDK, you have an awesome developer experience as well. So how do we create an awesome SDK so that we have an awesome developer experience? So that’s what I’m going to talk about today.
1. Great Documentation
Developer experience kit, or SDKs as they are generally known as. They encompass everything that is needed to call the API. So be it delivery code part, documentation … what I’ve done is I’ve put the documentation as the very first thing, because that’s what our developer will be seeing plant a flag on your website. They’ll want to read about what your product does, and how to get started with it as quickly as possible.
So and STRANDS docs come up a lot as a good example, because they have a great product documentation, and they have mixed up how-to guides and a seeker reference, all in one package, and your code samples, as well. So do you guys provide code samples for calling your API? Yeah? Because if you don’t, then you’re basically going straight down the dump.
I’ve seen this a lot, and the user test in every area, is that the first thing people do is just read what the directions says. And then they jump right to the pinpoint that they want to call, and they copy the code sample. So it’s pretty much the second or third thing that they do.
“If you’re not giving code samples, you’re basically missing a very big step in your developer experience.”
2. No-Frills SDK Setup
So the next thing is that I want to go into what SDK design would actually look like. What you want to do is make sure that the SDK is pretty easy to set up, so if you are writing a query, you will want to keep it as simple as possible. So if your SDK takes some configuration like if you are using OAuth2, you shouldn’t expect the deliverers to have very good RFC portal too, because that’s a lot of steps. And there’s a lot of stuff that goes into making OAuth2 work. Just give them the exact metrics that they need to call, and give them the exact links that give them the API key.
So I’ve copied this from Google’s SDK database, so that made it pretty clear how to get started in a couple of steps. Also, you want to make sure that your SDK design is pretty simple. Just don’t get carried away and start exposing the HTTP stuff to the user.
“Your SDK should only give metrics to call into the product.”
The user doesn’t have to know how the HTTP codes are built. You shouldn’t force them to remember what the headers are, what the body structure looks like. If you’re using an SDK, you already should have all the process and the metrics needed to call into an SDK.
3. Intuitive, KISS Design
One cool thing that you can do is make sure that the API design and the SDK design has a pretty neat correlation between them. So if I wanted to see the API, I should be able to guess what the SDK is going to look like. And sometimes this just doesn’t actually happen. People do get carried away.
So there’s another possible design. If you are basically targeting a lot of MBC or web developers, you might also see a different design in SDKs which basically copies what active records look like. So there are resources and there are metrics on resources. The other alternate design is equally well. The idea is just keep it as simple as possible.
4. Utilities for Common Use-Cases
Also, so if you have a product that does a lot of stuff that’s connected together … so if, for example, if you are making an API for an airline booking system, what you would want to do is if there are multiple API calls that need to happen, one after another, you will want to provide utility metrics that connect those API code.
“So don’t make the user guess what to do next. You have to write the documentation and provide the exact metrics in your SDK.“
So if there’s a flow that needs to happen for to book a ticket. The call should be as simple as searching for a flight, booking the ticket, making the payment … that’s right, adding a passenger, and then making the payment for it. So you just have to wrap all of that context stuff and make it easy to consume. Your other cases that I’ve seen as well. So most of the APIs need authentication configuration, right?
So if you are creating a SDK blind instance, what you should do is make sure that it already has the metrics to learn the configuration from environment. And there a lot of other stuff like that as well.
5. Helpful error messages
They’re pretty important when things go wrong. So the SDK shouldn’t accrue an exception that just says “the call was not okay and 404.” That doesn’t make sense to the developer who is using the SDK. You shouldn’t have to know what HTTP code went wrong. They should be shown a product-specific message which shows that this thing was wrong in his code and how to correct that.
If we’re being modest, if you could block all other requested responses that are going through your SDK, they help a lot when you have to provide support later, because you will then have exactly a lot of what was passed between the SDK and the API. And you can develop it from there. And there’s a bonus.
Whenever you accrue an exception, or if you’re showing an error to the user, you also provide a link to your documentation for how to recover from that error.
6. Enable Concurrency
Another thing an SDK should handle, and there’s actually quite a tough issue if you leave it to the user, is to enable concurrency. You should make sure that all the calls in your SDK lines are traced, and the request can be changed one after another. And since treading kind of messes up with the exceptions and all, you should also have a graceful way of recovering from the errors.
What we did at APIMatic was that in the next version of our SDKs, what we are doing is that we are making clients immutable, so what you have is that most of the clients and the classes that you normally interact with in the SDK are actually immutable. And if they have to mutate, some kind of string they have a small island of immutability or something that grabs the mutation, and so that the user doesn’t run into any kind of risky mutation.
And another good idea would be that if you have an SDK, that you’ll be using of that environment, you should take care that glasses for the blind should be sterilizable.
“That way, if the SDK calls will be creating multiple requests, you can basically save the client and restart it from your memory.”
So it’s a pretty cool feature if you can support that.
So right now, what I’ve talked is just all the basic stuff that all the SDK clients should have. But that would actually just make the SDKs mere API wrappers. So but writing SDK means that for the first time, you have the opportunity to run your port on your user’s server as well. So there’s a lot of good stuff that you can provide in your SDK.
7. Higher-Order Features
You can wrap around how sessions are working so that your user doesn’t have to figure out what cookies are needed, if there are cookies, if you are using cookies. And if you can rewrite your utility wrappers for odd, that would also be good. Your user shouldn’t have to figure out how pagination works at the API level. Your SDK should already have metrics for that. Retries, that’s pretty important for recovering from network problems, especially if you are writing a mobile SDK.
So throttling … your server should already have throttling, but the client should support recovering from a case when a server says, “Hey, back off and try again a couple of seconds later.”
Caching is just a performance feature, so it is the API calls are learning. Caching headers, you should try and do that.
Legible logging is pretty cool, especially when it comes to recovering from hard errors. And lastly, if you are using your SDK in a microservice setup internally, then you definitely need to add tracing into your API calls.
So you receive something that identifies it and this service center requests and the outgoing request should also have some kind of tracing information on it.
So that’s a lot of cool features you can add, but that’s not really an exhaustive list. What you want to do is that you would want to make your SDK as extensible as possible, so you have to argue that you’re going to wear that later more people can hook into the API calls.
8. Provide Hooks into API Call Events
So how can we look into the API calls? There’s one design that you can definitely copy from how MBC frameworks work, right, though is that they have this Middleware architecture. Middleware handlers, and then receive a request and then pass it to the next handler and then pass it to the next handler, until someone actually makes a response out of it and processor that of the spec.
You can actually use it to deliver all the features that I have talked about previously in my talks. In your SDK, you can structure it in a way that you can add logging, and you can add the retries as an after-thought feature. Or actually you can allow the user to override that if you are architecting your SDK in a way that it can be extended later.
9. Be a Good Library Maintainer
So you have written great documentation, you’re going to want to publish your API library to call an open-source repo. GitHub is what I recommend to everyone. So be a good maintainer and just learn all the issues.
“You must engage with your developers so that you know if your design is correct or if something isn’t working as expected.“
Another thing that you must keep on top of is vulnerabilities. So since you’re writing code that works with metric, you have to make sure that you are on top of all issues that are happening. And GitHub does a pretty good job, but they might not always have the latest vulnerabilities in their database, so it’s a good idea to keep on top of it yourself, too.
Do make sure that you’re using semantic versioning so that major and minor versions can be distinguished. And do provide a chain log so that it’s easy for people to migrate to the next window. And if you have written this for your SDK, it’s a good idea to share them publicly as well so that people have a spec to read and be able to contribute to your SDK as well.
So that’s all from my side. So if you guys have any suggestion for what goes in an awesome SDK, let me know.
View the full video from Mehdi’s presentation.