Building developer tools with OpenAPI
How we think about building developer tools as we scale
Developers integrate Paystack into their products through APIs or plugins. Over the years, the Developer Relations team, with the help of some amazing contributors, has built a rich catalog of plugins and tools for different platforms.
How do we ensure that we can build more tools as we scale to multiple countries, without losing the bandwidth to maintain the existing tools?
In this article, we share our approach to building the tools that improve developers' experience. If you’re thinking about how to scale your development of developer tools, we hope you find this instructive.
How we started
When we launched our developer documentation in 2020, we provided reference code snippets that demonstrate how our APIs work. The feedback we got made it clear that we could further enhance the usability of these snippets. To solve this problem, we needed to build more developer tools, starting with Software Development Kits (SDKs) for top programming languages.
An SDK is a collection of building blocks for the development of applications. Among other things, SDKs typically consist of functions that help developers achieve specific tasks in their applications.
To ensure that we could maintain each SDK, we needed an approach that would scale as Paystack scales. There were two ways to achieve this goal:
- Build SDKs from scratch for each language
- Automate the generation of SDKs
Building SDKs from scratch comes with some downsides:
- It requires dedicated resources for each language
- The initial development of these SDKs is time-consuming - Paystack has over 100 APIs
- When our APIs change, we’d need to coordinate the update for each SDK
These downsides could be addressed by putting processes in place, however, that would require significant time and effort. So we decided on the automation approach as it addresses the downsides, and comes with the added benefit of easy maintenance!
Deciding on the development stack
The automation process works because our APIs are RESTful, so we can leverage the properties of the HTTP method.
The properties of each HTTP method show how the SDK will function. The table shows that all POST endpoints will:
- Check for the availability of JSON data
- Parse JSON data when available
- Check for the availability of path parameters
These steps are repetitive, which means they can be represented with templates. Once the templates are created, scripts can be used to generate the necessary SDK functions for all endpoints.
There are several tools that can be used to generate SDKs. These tools require you to present your APIs in a structured format - mostly JSON and YAML. After testing different tools, we decided on the OpenAPI generator. This is an open-source tool that generates clients and server stubs from an OpenAPI specification. We chose the OpenAPI generator because it allows us to provide custom templates that control how our SDKs function.
Creating our OpenAPI specification
OpenAPI is an industry standard for designing and documenting APIs. API operations, models, and other components can be defined in JSON or YAML format.
The entry point of the OpenAPI specification is the OpenAPI object which consists of 8 top-level fields:
- openapi: This is used to specify the OpenAPI version being used. This is crucial because it tells tools how to parse the specification.
- info: This holds the details about your API like version, description etc.
- servers: This is where you specify the base URL(s) to access your API. If you have different URLs for your test and live environment, you’ll specify them in this field.
- tags: You typically categorize your APIs based on the resources they manipulate. Each category can be listed in the tags object.
- paths: The relative paths and operations for each endpoint reside in this field.
- components: This holds all reusable objects that can be referenced in different fields of the specification.
- security: You can define your API security scheme here. This includes user name and password, OAuth, Bearer token, etc.
- externalDocs: This allows you to reference other documentation that accompanies the specification.
An OpenAPI specification is framework-agnostic and its data format makes it human and machine-readable. You can use the OpenAPI specification as documentation for your APIs. Tools can also parse and use the specification to solve different problems. The OpenAPI generator parses the OpenAPI specification, using its fields to generate SDKs.
You can generate the OpenAPI specification directly from your existing codebase if your development stack supports it. Otherwise, the specification has to be created manually. This could be quite tedious. However, one way to go about it is by adding endpoints incrementally. Our OpenAPI specification is open source on GitHub for reference.
Generating SDKs with OpenAPI Generator
The OpenAPI generator is a Java-based tool for generating SDKs from an OpenAPI specification. It supports the generation of clients, servers, and documentation by using:
- An OpenAPI specification
- A language-specific template
- A configuration file
Since we already have an OpenAPI specification, we focused on other components.
Creating custom templates
A template is like a mold for creating exact replicas of an item. Likewise, the OpenAPI generator needs templates to transform the OpenAPI specification into SDKs. The OpenAPI generator ships with default templates, represented as mustache files for each supported language.
The output generated from the default template might suffice, depending on your use case and preference. However, we decided to use the customization feature of the OpenAPI generator, to get a cleaner SDK output.
To customize a template, you begin by extracting the default template to your working directory using the command:
openapi-generator-cli author template -g typescript --library webclient
This command extracts the default typescript template into the current working directory. Once extracted, we could make the necessary modifications based on our preferences. You might benefit from approaching this phase like you’d approach code refactoring. Work in bits, test the outcome, and repeat till you achieve your goal.
Creating configuration files
The configuration file contains the instructions on how the SDK should be generated. The configuration for each language is also baked into the generator by default. Since we had a custom template and wanted to fine-tune some of the generation steps, we overrode the default configuration file.
The configuration file is a YAML file which means its content is a key-value pair. The key-value pairs are self-descriptive. The inputSpec takes the location of the OpenAPI specification. The templateDir allows us to point to our custom template etc.
With all components now in place, we could generate an SDK with the following command:
npx @openapitools/openapi-generator-cli generate -c ./config/node.yaml
There’s also a command for generating all SDKs at the same time:
npx @openapitools/openapi-generator-cli batch ./config/*.yml
With OpenAPI and the OpenAPI generator, we have a central location for building and maintaining all our SDKs. This saves us time and effort as we make product changes and expand into new regions. That means you can easily access an up-to-date version of our tools.
Benefits of building with OpenAPI
Our OpenAPI specification has opened a lot of opportunities for us in the mid and long term. Some of these benefits are:
- Comprehensive documentation of our APIs
- Single source of truth for developer tools
- Avenue for collaboration with open-source contributors
- Ease of maintenance
- Automation of repetitive tasks
- Delighted developers
There’s so much to explore with the OpenAPI specification. You can easily manipulate the data format based on your use case. Other explorations of the OpenAPI specification on our radar are:
- Fully integrate OpenAPI into our Postman workspace: We recently created our Postman workspace containing our APIs and popular use case collections, all from the OpenAPI specification. Updates to the Postman workspace are currently done manually and we’d like to close the loop by automating the process.
- Generate SDKs in top languages: We plan to generate SDKs for other languages, with a focus on PHP, Ruby, Java, and C# next.
- Power our API reference with the specification: Since our API reference is a collection of components generated from different data sources, we could replace the data source with the OpenAPI specification.
- Power the CLI with the specification: Our CLI currently maintains its copy of JSON data for all endpoints. This can be replaced with the OpenAPI specification to ensure its API lists are always up-to-date.
At Paystack, we’re always on the lookout for ways to improve the developer experience across our products. Developers are already solving difficult problems. Integrating payments tools should not be one more item on that list. With developer tools, integration times can be shortened significantly.
For more updates on the tools we're building for you, subscribe to our developer newsletter ✨
Subscribe to our Developer Monthly Roundup
Subscribe to get updates about new developer toolsSubscribe