Building Better SDKs
Friday, January 14, 2022
Nathan Darst |
Nathan Darst is the Director of SDK Engineering for Kochava and discusses how developers can start building better SDKs, what a good API looks like, how to integrate an SDK and use it in code, how an API can protect users, why an API should change as little as possible and a lot more.
Nathan Darst is the Director of SDK Engineering for Kochava, a real-time data solutions company offering the leading omnichannel measurement and attribution solutions for data-driven marketers. Darst talks about building better SDKs, integrating them, using an SDK in code, what good APIs look like, and a ton more.
You've written some amazing code; so amazing that you've separated this code into its own library for use in your other apps. This works great while you're the author of both the app and the library because you can make any needed adjustments on the fly. But, what if you want to share this library with hundreds or even thousands of other developers? Suddenly the landscape changes and new questions must be answered:
1. Is it easy to use?
2. Will it play nicely with any app in any environment?
3. How will it impact the app's footprint?
4. Has it been thoroughly tested?
If these questions excite you, you've got a bright future in SDK development! If not, you've probably used an SDK or two and may find it interesting to learn more about some of the unique challenges of SDK development.
Building Better SDKs
So what exactly is an SDK? Short for "software development kit", you may also know it as a library, a plugin, a package, a dependency, a module, or a number of other terms to be forever debated on developer forums. Semantics aside, the goal of SDK development is to make life easy for other developers. SDKs solve problems, remove barriers, and most importantly make it possible for time and resources to be focused on real content rather than reinventing the wheel.
Need to add JSON parsing capability to your app? There's an SDK for that. Need to add analytics to your app? There's an SDK for that. Want to monetize your app through advertising? There's an SDK for that.
Sounds great, doesn't it? Problems need solving, and that's what SDKs do.
The bad news is nobody wants to integrate an SDK into their app. The functionality it brings may be desired, but adding an SDK means adding more app bloat, more code to maintain, and more dependencies to juggle, often in perpetuity. The challenge with SDK development is not only to offer up the promised functionality but to do so as painlessly as possible. A well-designed SDK performs its duties quietly, is rarely noticed and is easily forgotten.
To that end, we'll take a deeper dive into the original list of questions through the lens of SDK development.
1. Is it easy to use?
Let's talk about user experience (commonly referred to as UX), we've all heard of it. It's vital to any app, game, site, or software designed to be used by humans. A good UX is the result of intuitive design and allows the interface between user and software to get out of the way so the actual content and experience can shine through. Conversely, a bad UX means the user is going to spend a disproportionate amount of time trying to figure out how things work and how to accomplish even basic tasks, and probably go looking online for answers.
Unfortunately, UX is often neglected in SDK design as the focus tends to skew towards the internals and functionality of an SDK, with UX being more of an afterthought. This UX neglect manifests itself as a clunky integration process or poorly designed API (application programming interface), which in turn can mar an otherwise fantastic SDK.
Let's look more closely at what makes up the UX of an SDK: the integration process and the API.
The Integration
Before a developer can use an SDK, they need to integrate it. This usually involves downloading the SDK in some way, so that the SDK is available locally in their development environment.
In the old days, integrating an SDK usually meant manually downloading or getting a physical copy of it, and then following a number of steps to correctly link it into the project.
In today's world, while a manual download is sometimes necessary, much of this process can be automated for the developer via package managers and repositories. A package manager can be thought of as a storefront for developer tools, similar to a store for apps. When an SDK is available through a package manager, the integration process is much simpler for the developer and is usually accomplished by browsing or providing a path to the SDK. The package manager handles pulling in the proper SDK version and in most cases will also handle pulling in any necessary dependencies automatically. Examples of package managers you've probably heard of or even used yourself include npm, CocoaPods, Maven/Gradle, Swift Package Manager, NuGet, and many more.
Package managers are a boon for developers, and the SDK developer should leverage them whenever possible. However, this comes at a cost, and that cost is shifted to the developer of the SDK. Multiple package managers exist across each platform today, and new ones continue to pop up, each with its own quirks, and developers may have their own preferences or restrictions regarding which package managers they can use. To reach every developer, the SDK must be packaged up and published across as many of these package managers as is warranted, which in turn means more maintenance and overhead for the SDK developer. But despite the overhead, this effort ensures SDK integration is smooth as butter for any developer.
In short, SDK development requires keeping a vigilant eye on the ever-changing integration landscape, and taking any steps necessary to ensure integration is as painless as possible for all developers.
The API
Once a developer has integrated the SDK, the next step is actually using the SDK in code. The SDK's API defines how a developer will interact with the SDK in code and is where the rubber meets the road in terms of UX. A good API results in a positive experience and efficient use of developer time, while a poorly designed API results in both wasted time and potentially botched integrations which may not even come to light until after code has been pushed to production.
So, what does a good API look like?
This is where we have to be willing to step outside of our comfort zone a bit and make design decisions not from a computer science theory point of view, but from a user-first point of view. Remember that the API does not exist for the benefit of the SDK developer or those maintaining the SDK code. Rather, the API exists solely for the user of the SDK, and all API design decisions should reflect this.
Simplicity & Purpose
The developer wants to solve a problem, and the API should facilitate solving this problem quickly and intuitively with as few lines of code as possible. A good API prioritizes and focuses on the most common use cases; it is not muddied up with unnecessary, ambiguous, redundant, or rarely used functionality likely to confuse the user.
Accessibility
A good API is designed to be accessible regardless of developer expertise with the platform or even language. Developers often work on multiple projects and sometimes across platforms. The developer who integrated the SDK into the Android version of the app today may find themselves integrating it into the iOS version of the app tomorrow. The API must be drop-dead simple and work for novice developers who may not always be familiar with the latest and greatest programming techniques.
Platform Parity
The parity of high-level concepts and API usage must be strived for across platforms. While the internals of the SDK may be wildly different between Android and iOS, for example, the API side should remain as consistent as possible across these platforms.
Don't Hide Behind Documentation
It may be tempting to write off a clunky or over-architected API because the user can always "consult the documentation." While documentation is a must, an intuitive API should be usable with as little time spent in documentation as possible. There should be an "ah-ha" moment for the developer once they see the code and check the documentation, things should click and immediately make sense in their mind. Returned trips to the documentation should only be necessary to learn more.
Avoid Change
This may be a controversial one, but an API should change as little as possible. Users don't want to update SDK versions in the first place, and they certainly don't want to be forced to update all of their SDK-related code when they do update their SDK version. A good API is rarely updated, and only when absolutely necessary.
Put Up Guard Rails
A good API can protect users from themselves. Developers make mistakes and a good API will both limit the opportunity for these mistakes and ideally fail to compile when a mistake is present. When a mistake is allowed to compile and fails at runtime, the developer is much less likely to catch it and could push a botched SDK integration to production.
Remember that the user of the SDK wants to spend as little time as possible tinkering with the SDK and does not want to revisit the code after integration is complete. A good API facilitates this.
Read more: https://www.kochava.com
This content is made possible by a guest author, or sponsor; it is not written by and does not necessarily reflect the views of App Developer Magazine's editorial staff.
Become a subscriber of App Developer Magazine for just $5.99 a month and take advantage of all these perks.
MEMBERS GET ACCESS TO
- - Exclusive content from leaders in the industry
- - Q&A articles from industry leaders
- - Tips and tricks from the most successful developers weekly
- - Monthly issues, including all 90+ back-issues since 2012
- - Event discounts and early-bird signups
- - Gain insight from top achievers in the app store
- - Learn what tools to use, what SDK's to use, and more
Subscribe here