8 Tips to Make Your SDK More Wicked than Elphaba Thropp

Brian Lewis
Ordergroove Engineering
6 min readFeb 1, 2019

Introduction

Elphaba Thropp, also known as the Wicked Witch of the West, can concoct brews, harness the will of snow monkeys, and perform a host of other allurements. A well-designed SDK can be just as wickedly powerful — provided you keep in mind the following tips.

1. Namespace your methods

Namespace your SDK methods such that their intentions do not require divination to ascertain. Adopt a well-considered naming convention and use it consistently. A naming convention should not only reveal the purpose of the method, but identify the thing upon which the method acts as well.

Your SDK’s naming convention should reflect the nature of the system with which it primarily interfaces. If, for example, your SDK primarily interfaces with a RESTful API, a sensible naming convention might be <sdk>.<resource>.<method>, where <sdk> is the name of your SDK, <resource> is the name of the resource upon which the method acts, and <method> is one of a consistent set of operations such as get, create, update, and delete.

Thoughtful namespacing is fun and fundamental to making your SDK easy to understand and effortless to use.

2. Embrace configurability

A useful SDK is one that simplifies the workload of those who use it. Supporting a degree of configurability can help simplify method calls and keep code DRY.

Imagine your SDK contains methods that make requests to an API. The API expects a particular authentication header. One option would be to pass the configuration required for the header into each method call. Another would be to pass the configuration in once either at initialization or via an explicit call to a configuration method. The SDK would then send the header with each request. In the latter approach, the intent of the SDK method is isolated from the need to authenticate. The resultant method signature is simpler.

A configureable SDK frees users from the need to keep track of information not necessarily relevant to the purpose of the SDK method itself. A free SDK user is a productive one.

3. Marshal your data

Unlike Elphaba, who seeks to seed disarray, SDKs should seek to facilitate interoperability between systems. To this end, your SDK should take the extra step of marshaling input and output data.

Imagine a JavaScript SDK makes a request to a system written in Python. The SDK would be wise to marshal data represented in JavaScript’s preferred convention of lowerCamelCase to Python’s preferred convention of snake_case, and send the marshaled data with the request. Likewise, the SDK would be wise to unmarshal the snake_case response data to lowerCamelCase, so it can reside amongst the calling JavaScript code seamlessly.

Marshaling data helps bridge the gap between systems by eliminating the need to manually convert or otherwise account for idiosyncrasies with formats and types of input and output data.

4. Cache your requests

If your SDK facilitates frequent read operations, you have an opportunity to provide value to your users in the form of cacheing. Cacheing can improve performance by eliminating the need to repeatedly request data from an interfacing system.

It’s likely that a request cacheing tool exists for your SDK’s language of choice. Examples include Ehcache for Java, superagent-cache-plugin for JavaScript, and quick-cache for Elm. Cacheing properly is a science unto itself, so in the off chance no suitable library exists, resist the temptation to roll your own and simultaneously blow up scope.

Cacheing data retrieval operations is a prime example of how an SDK can provide tangible value. If your SDK can retrieve data from a cache rather than from the interfacing system itself, applications using the SDK will enjoy the transcendent benefit of improved performance.

5. Orchestrate complex actions

An SDK that solely serves as a proxy to the actions of its interfacing systems is useful, but one that goes beyond mere proxying is indispensable. Up the value of your SDK by orchestrating complex actions. First, identify which combinations of actions users frequently perform. Next, orchestrate the invocation of those actions and expose a single method.

Imagine your SDK interfaces with a system that applies heat to potions. The heat-applying system exposes only granular methods such as boil, bubble, and roil. Assuming users frequently do all three, your SDK would be wise to orchestrate the actions and expose a single method, heat.

The ability to apply heat to a potion with an economy of effort is undeniably valuable to a sorceress. The ability to perform a complex action via a single method call is equally valuable to an SDK user.

6. Version your SDK

Avoid surprising your users by identifying a versioning technique and sticking to it. There’s no universally agreed upon versioning technique, so select one suitable to your project.

Artifacts crucial to supporting good versioning include release notes, a changelog, and a support schedule. Release notes should be written in a friendly, brand-consistent voice. They should describe at a high level added features, enhancements, and bug fixes. A changelog should describe in technical terms what has changed since the previous version. It should provide links to relevant commits or discussions to provide context. Breaking changes should be called out in no uncertain terms. A support schedule should delineate which prior versions you support, and when versions will be deprecated. Deprecated versions should be clearly marked as such in all places they’re referenced.

Good versioning practices improve transparency, which in turn promotes trust. A developer who trusts your SDK is more likely to start using it, continue using it, and encourage others to use it.

7. Document your SDK

If it’s not apparent how to use your SDK, nary a soul will use it. Thorough documentation is critical. Each aspect of your SDK should be documented.

Make your life easy by using tools that facilitate documentation. Tools such as Sphinx for Python, React DOC Generator for React, and Jazzy for Swift generate documentation automatically based on annotations or markdown in your code. Services such Read the Docs and GitHub Pages provide documentation hosting. In addition to documenting your SDK methods, give setup instructions a fair gestation as well. Their presence will ease the uncertainty your SDK users face during the potentially perilous time of initial setup.

Improve your documentation by leaps and bounds by including interactivity. If a user can invoke your SDK methods and observe the responses from the documentation itself, the user will surely be smitten. Not only is interactivity a great tool for learning the subtleties of your SDK, it can also help a user debug their projects that use it.

The entirety of your SDK’s documentation should fall right to hand. Either link to or include in your documentation your release notes, changelog, and support schedule. Consider making your documentation public. If a user can access your documentation without logging in, they’ll be more likely to read it.

8. Add a functional test suite

Unless you update your SDK in lockstep with updates to the systems with which it interfaces, you expose yourself to risks associated with drift. In this context, drift can be defined as the scenario in which the expectations of one system diverge from the realities of other systems with which it interfaces. Unlike unit tests, which often use mocks, functional tests make assertions based on results from live instances of interfacing systems.

A functional test suite helps you identify drift early, so you can correct for it before changes are ever released. To get the full benefit of your functional test suite, configure it to run automatically when changes are made to either your SDK or to any system with which it directly or indirectly interfaces. Consider configuring your functional test suite to run pre-commit, pre-push, prior to merging to a protected branch, prior to deployment, or any appropriate combination thereof.

As an added bonus, a functional test suite for your SDK provides implicit functional test coverage of the systems with which it interfaces themselves (at least for the portion of those systems that the SDK uses).

Conclusion

Elphaba’s recipe for success is one part dastard and one part wicked. Don’t be afraid to make your SDK both dastardly useful and wickedly powerful. Take time to consider what your users authentically want. If you can make their lives easier, you can lock them in as advocates. Your ideal user is able to identify so many benefits to using your SDK that to not use it would be unconscionable.

--

--