Generate SDKs with Speakeasy
The quicker a customer can integrate with your API, the quicker your business will be making money or solving problems. Some users will be happy to integrate directly with the API, but many prefer the ease of working within the programming language through Software Development Kits (SDKs).
These can be a lot of work to build and keep up to date, but if you’ve got OpenAPI you really don’t need to do all that manually. Generate them automatically with Speakeasy, and publish the code samples to your Bump.sh API documentation!
What is Speakeasy #
Speakeasy is Software-as-a-Service similar to Bump.sh, but instead of focusing on documentation they focus on SDK generation. In the past you’d have to use cumbersome Java-based open-source tooling and generally develop your own templates, but with Speakeasy you can simply upload an OpenAPI description document and get type-safe SDKs that your team will be proud of: include OAuth2.0, retries, pagination, custom code, and more.
Step 1: Set up Speakeasy #
Head over the Speakeasy Quickstart or if you’d like to go a little slower you can go through the Speakeasy Introduction. The main thing is to start with installing the Speakeasy CLI which you can do with popular package managers like Homebrew and Chocolatey.
Step 2: Create Your First SDK #
Once you’ve got Speakeasy CLI set up, run the speakeasy quickstart
command. You’ll be prompted to generate a workspace on their dashboard if you haven’t already.
The CLI quickstart wizard will walk you through the process of creating the first SDK, by asking you to point to your OpenAPI document and pick the first language.
For the sake of the tutorial we’re going with TypeScript, but you can pick from Python, Go, Java, PHP, C#, Ruby, Swift, and more.
Generally, you’ll have a “central” repository which contains your OpenAPI, and Speakeasy suggests creating a new repository for each SDK you generate (although monorepo setups are possible). This repository will hold all the code and the relevant configuration to keep it all running, separate from your main OpenAPI and source code.
For example, if you ran the speakeasy quickstart
from /Users/phil/src/train-travel-api
, you might make a new repository for the TypeScript SDK next to that directory in /Users/phil/src/train-travel-sdk-ts
.
Enter a path like that into the quickstart, and the local Git repository will be created for you. You can add, commit, and push everything to a new GitHub repository of your choosing.
cd ~/src/train-travel-sdk-ts
git remote add origin git@github.com:bump-sh-examples/train-travel-sdk-ts.git
git add --all
git commit -m "initial commit"
git push origin main
Once you’ve got everything inside this lovely new generated codebase pushed to GitHub, you can create GitHub Actions to automatically create pull requests when changes are detected on the OpenAPI.
Step 3: Configure GitHub #
GitHub Actions help us to automate generating and releasing new versions of the SDKs over time as your API and the OpenAPI that describes it evolve.
speakeasy configure github
This create a new .github/workflows/sdk_generation.yaml
which will do a few things. It’s main job is to set up a cron job which will open pull requests to generate a new SDK for you once a day if there are changes. To make it work check the output of that command which outlines a bunch of steps, from creating an SPEAKEASY_API_KEY
environment variables, and allowing the GitHub Action to open up pull requests.
One other thing, to make this work on GitHub instead of just working locally, is to update the “target” in the Speakeasy SDK workflow document: .speakeasy/workflow.yaml
.
By default it was set to the following:
sources:
Train Travel API:
inputs:
- location: ../train-travel-api/openapi.yaml
This was causing some confusion for the Speakeasy GitHub action because it was literally looking for that local path when the GitHub Action was being run, and that’s the folder structure on the local machine which isn’t there. To make this work on GitHub you can grab the public “raw” URL:
sources:
Train Travel API:
inputs:
- location: https://raw.githubusercontent.com/bump-sh-examples/train-travel-api/refs/heads/main/openapi.yaml
Public URLs like this will only work for public GitHub repos, but if you cannot make the repo public you can pop this onto S3 or somewhere else.
Please do all of these steps or things will not work.
Commit and push all of these changes to main, and the repository is in good shape.
Step 4: Publish Code to Package Managers #
Once GitHub is automatically creating pull requests to update the codebase in your repository, you might want to do something with that code, like publish that code as a package to package managers like NPM, PyPI, Packagist, NuGet, and Maven.
For the sake of the tutorial, we’re publishing to NPM. The easiest way is to follow the standard process of creating a NPM package, by doing it manually at first, then letting Speakeasy take over after.
npm login
npm publish
If this all worked then count to 100 and you should see your new package!
Now our train-travel-sdk
actually exists online, and you can see how it’s going from here.
To save somebody having to run a command to publish this SDK (and every other SDK you end up making) every time anything changes, we can ask GitHub and Speakeasy to handle all of that for us.
speakeasy configure publishing
This will create another github workflow which will help publish the package automatically, and should look a bit like this:
name: Publish
permissions:
checks: write
contents: write
pull-requests: write
statuses: write
id-token: write
"on":
push:
branches:
- main
paths:
- .speakeasy/gen.lock
workflow_dispatch: {}
jobs:
publish:
uses: speakeasy-api/sdk-generation-action/.github/workflows/sdk-publish.yaml@v15
with:
target: train-travel-sdk
secrets:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
npm_token: ${{ secrets.NPM_TOKEN }}
speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }}
Notice it is still using the SPEAKEASY_API_KEY
that we used in the generate workflow, but now there’s a NPM_TOKEN
we’ll need to add. Grab that from your NPM account under Access Tokens, make sure it has write permission for packages, and save it as NPM_TOKEN
in your repo GitHub repository Actions secrets.
Now if you push commits your main branch or merge a pull request, this GitHub Action will automatically help publish a new version of the SDK.
From here, if you change anything relevant in the SDK repo, it’ll publish a new SDK, and if the central OpenAPI changes it will also publish a new SDK. This solves a lot of the frustrations with managing packages too, such as manually bumping version numbers and figuring out if it should be major, minor, or patch, or setting up confusing conventions for automatically doing it like Semantic Release. Speakeasy and GitHub Actions (or similar) can just do all that for you as changes are merged.
With everything be entirely automated we can leave the SDK to itself, and the DevRel team can focus on tell everyone about how amazing it is.
Step 5: Integrating Code Samples into OpenAPI with Overlays #
In the past people would either have completely separate “API Docs” and “SDK Docs”, or they would spend countless hours copying and pasting SDK examples into the API Docs.
No more!
You can grab the latest SDK code samples right from Speakeasy, and merge them into your Bump.sh API documentation using OpenAPI Overlays which Speakeasy create for you.
If you don’t know what Overlays are, that’s ok, you don’t really need to. Simply, they are a list of changes that should be applied to an OpenAPI document, and Speakeasy has done the hard work of making them already, so all you need to do is grab a URL. To do this, head to the API registry and look for something like “train-travel-api-typescript-code-samples”.
Check the private/public toggle on, and copy the URL. Paste it into your browser to see how it looks, and you should see something like this:
This overlay document will show you exactly what it’s trying to do. It has a series of actions
, which look for a specific target
within the OpenAPI, and update the x-codeSamples
with a perfect example of the SDK in action for every single operation in your OpenAPI document.
overlay: 1.0.0
info:
title: CodeSamples overlay for typescript target
version: 0.0.0
actions:
- target: $["paths"]["/bookings"]["get"]
update:
x-codeSamples:
- lang: typescript
label: bookings
source: |-
import { TrainTravelSDK } from "train-travel-sdk";
const trainTravelSDK = new TrainTravelSDK({
oAuth2: process.env["TRAINTRAVELSDK_O_AUTH2"] ?? "",
});
async function run() {
const result = await trainTravelSDK.bookings.list({
page: 1,
limit: 10,
});
// Handle the result
console.log(result);
}
run();
The overlay will be much bigger than this, and it might not make sense to look at it directly, so lets apply it to an OpenAPI document to see how it all fits together. The Bump.sh CLI can help us out here.
Switch back to the repository where your OpenAPI document lives.
bump overlay openapi.yaml \
https://spec.speakeasy.com/bumpsh/bumpsh/train-travel-api-typescript-code-samples \
> openapi.codegen.yaml
Updating openapi.yaml
to wherever your OpenAPI document lives, and https://spec.speakeasy.com/bumpsh/bumpsh/train-travel-api-typescript-code-samples
URL to whatever URL you copied from the API Registry entry labelled with “Code Samples”, then openapi.codegen.yaml
will be the output of those overlays once applied to the OpenAPI.
As always you can use Bump.sh to get a proper view of an OpenAPI document as human-readable API documentation, so lets point it at our newly overlayed document.
bump preview openapi.codegen.yaml
Open the preview link in the CLI output and you should see something like this:
Amazing! The TypeScript SDK is now integrated into the API documentation, and the consumer doesn’t have to look at cURL commands to see how they might work with the API.
Step 6: Applying Code Sample Overlays on Bump.sh Deployments #
To get this deployed you can do the same thing you just did, run the overlay then publish the resulting document. This will work on any continuous integration solution, just deploy the temporary created document instead of the original.
In GitHub Actions, it will work like this:
# .github/workflows/bump.yml
name: Deploy API documentation
on:
push:
branches:
- main
jobs:
deploy-doc:
if: ${{ github.event_name == 'push' }}
name: Deploy API documentation on Bump.sh
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Add TypeScript SDK Samples to OpenAPI
run: |
npx bump-cli overlay openapi.yaml \
https://spec.speakeasy.com/bumpsh/bumpsh/train-travel-api-typescript-code-samples \
> openapi.codegen.yaml
- name: Deploy API documentation
uses: bump-sh/github-action@v1
with:
doc: <your-doc-id-or-slug>
token: ${{secrets.BUMP_TOKEN}}
file: openapi.codegen.yaml
That’s all you need to do. Commit that, and you’ll be generating and deploying OpenAPI-based API Reference Documentation with the very latest version of the code samples.
See how they look here on the hosted Train Travel API documentation.
Next Steps #
Documenting Multiple SDKs
To generate multiple SDK languages just repeat the process, to create another SDK on Speakeasy, with another repo, get that repo automated, then in the central repository containing the OpenAPI add more lines to the overlay command.
- name: Add TypeScript SDK Samples to OpenAPI
run: |
npx bump-cli overlay openapi.yaml \
https://spec.speakeasy.com/bumpsh/bumpsh/train-travel-api-typescript-code-samples \
> openapi.codegen1.yaml
- name: Add PHP SDK Samples to OpenAPI
run: |
npx bump-cli overlay openapi.codegen1.yaml \
https://spec.speakeasy.com/bumpsh/bumpsh/train-travel-api-php-code-samples \
> openapi.codegen2.yaml
- name: Deploy API documentation
uses: bump-sh/github-action@v1
with:
doc: <your-doc-id-or-slug>
token: ${{secrets.BUMP_TOKEN}}
file: openapi.codegen2.yaml
Including SDK Setup Instructions
If you’d like to add some extra documentation about how to install these SDKs for your users, check out our guides on Topics, or update the existing OpenAPI with overlays of your own.