Writing SDKs
An SDK is a collections of APIs designed to achieve a specific goal. For example, the Stripe SDK is a collection of APIs that allow developers to interact with the Stripe payment platform in a more convenient way.
When you need external functionality in your code, you can either write the code yourself or use an SDK that provides the functionality you need.
The above implies that an SDK is an intermediary between your code and the target service or platform.
By doing so, it implies that you are not only inheriting the functionality provided by the SDK, but also the technical design decisions, the architecture, and the bad parts e.g security vulnerabilities.
Therefore, as SDK architects, it’s imperative that we design SDKs that are easy, scalable and simple to work with.
Types of SDKs
There are multiple types of SDKs, including:
Mobile SDKs: These are SDKs designed for mobile platforms such as iOS and Android. They provide APIs for interacting with the mobile platform’s features and services.
Web SDKs: These are SDKs designed for web platforms such as JavaScript and TypeScript. They provide APIs for interacting with web platforms’ features and services.
Server SDKs: These are SDKs designed for server-side platforms such as Node.js, Python, and Go. They provide APIs for interacting with server-side platforms’ features and services.
Platform SDKs: These are SDKs designed for specific platforms such as Windows, macOS, and Linux. They provide APIs for interacting with the platform’s features and services.
SDK Usage Example
Suppose, we want to interact with the Stripe payment platform in our code. We can either write the code to interact with the Stripe API ourselves or use the Stripe SDK.
Using the Stripe SDK, we can easily create a payment intent like this:
| |
If we hand to write the code ourselves, we would have to make an HTTP request to the Stripe API endpoint for creating a payment intent, handle authentication, and parse the response.
| |
Why use an SDK in the first place?
Simplification of application development through abstraction of complex functionalities and services.
Saves development time since developers can easily pickout what they need from different services or platforms.
Modularity of codebases hence better readability.
What makes an SDK “good”?
When developers say an SDK is good and easy to work with, what metrics do we normally use to make the judgement?
A good SDK should be:
Simple
Imagine having to unwield a messy implementation trying to figurue out how to use the damn thing. In frustation, the developers choose to find alternative means of performing whatever action they want to achieve.
Operational
The SDK should serve it’s intended purpose and provide the functionality that developers need to interact with the target service or platform.
Expressive
An expressive SDK API provides a clear and intuitive interface for developers to interact with the service or platform. It should be easy to understand and use, and should provide a consistent experience across different programming languages and platforms.
Follows the language’s idioms and conventions
Following the target language’s idioms and conventions makes the SDK feel more natural and intuitive to developers who are familiar with the language. It also helps to reduce the learning curve for developers who are new to the language.
For example, if you are writing an SDK using JavaScript, you should follow JavaScript’s conventions for naming, error handling, and asynchronous programming. This will make the SDK feel more natural to JavaScript developers and will make it easier for them to use the SDK in their projects.
Predictable
No magic should be related to how your SDK works. The output should always be predictable based on the input. This not only allows developers to understand how the SDK works and what to expect when using it but also ensures a smooth developer experience should an issue arise.
I have written a few SDKs in the past, and this has always left me wondering what a good SDK should look like.
So, I went down a rabbit hole of researching about what makes an SDK great both for it’s intended use and for the developers who will be using it.
1. Focus on server side logic.
This implies that you do not intermingle with client side logic. This allows for better separation of concerns and makes it easier to maintain and update the SDK.
For example, if you are writing an SDK for a payment platform, you should focus on providing APIs for interacting with the payment platform’s features and services, rather than providing APIs for handling client-side logic such as form validation or UI components.
2. Provide clear and concise documentation.
This is crucial for developers to understand how to use the SDK and what it can do. The documentation should include examples, use cases and best practices for using the SDK.
The examples should be simple and easy to understand, and should cover a limited range of use cases.
For example, if you are providing an example of how to create a payment intent using the Stripe SDK, you should provide a simple example that shows how to create a payment intent with the minimum required parameters, rather than pproviding a complex example that includes all possible parameters and options.
3. Changelog and versioning.
This allows developers to keep track of changes and updates to the SDK, and ensures that they are using the correct version for their needs.
4. SDK should be lean and lightweight.
This means that it should not include unnecessary features or dependencies that can bloat the SDK and make it harder to use. A good SDK should be focused on providing the core functionality that developers need to interact with the service or platform.
A large SDK increases your users’ app sizes which in turn increases build times, which in turn increases, for example the CI/CD pipeline times. Longer pipelines mean more expensive pipelines, which means more expensive software development for your users.
5. Add telemetry and logging.
This allows you to track how developers are using the SDK and identify any issues or bugs that may arise. It also allows you to gather feedback from developers and improve the SDK over time.
It is hard to improve on your solution’s delivery if you don’t have any data on how it’s being used.
The caveat is that too much tracking can be invasive and can raise privacy concerns. Strike a balance between gathering useful data and respecting developers’ privacy.
6. Treat SDKs as modules.
A module is a self-contained unit of functionality that can be easily imported and used in a project.
This means that you should design the SDK in a way that allows developers to use only the parts of the SDK that they need, without having to include the entire SDK in their project. This can be achieved through modular design and allowing developers to import only the specific modules they need.
For example, if I need to use the Stripe SDK to create a payment intent, I should be able to import only the payment intent module, rather than having to import the entire Stripe SDK in my application’s bundle.
7. Begin with the end in mind.
An SDK’s main purpose is to make it easier for developers to interact with a service or platform. Therefore, when designing an SDK, it’s important to keep the end user in mind and design the SDK in a way that is intuitive and easy to use.
8. Mind about error handling and edge cases.
A good SDK should handle errors gracefully and provide clear error messages to developers. It should also account for edge cases and provide solutions for handling them.