How Square makes its SDKs

At Square we leverage the OpenAPI standard, Travis CI & Github to build and deliver our client SDKs in a scalable way.

The developer platform team at Square is a little different than most. We don’t focus solely on creating the APIs that our developers use, we focus on exposing the internal APIs that our first-party products use to create the best experience for developers. That way, our external developers get to use the same source of truth for all of our shared customer’s information.

Square’s internal structure

An important factor in why we make our SDKs this way is the structure of Square’s product teams internally. Like many companies, Square operates a variety of different services to run different parts of the customer experience, each with a dedicated team to make sure everything is working properly while adding new features. Our developer platform team works to expose these internal services to the outside world, while handling things that are important to our third-party developers like authorization, rate limiting, and more. Our team works hard to enable other teams within Square to quickly and easily expose their APIs to the world, and having to write an SDK for a new feature release shouldn’t act as a bottleneck.

SDK Generation

Instead of writing each of our SDKs by hand (which would not only be time consuming, but slow down the release of new features into the SDKs) we use a process that relies heavily on SDK generation. It all starts with our specification.

Our API specification

We use the OpenAPI (formerly known as Swagger) standard to define our APIs. This is just a JSON (or YAML) file that defines the urls of our API endpoints, what kind of HTTP request to make, as well as what kind of information to provide, or expect to get back. Our specification is made up of 3 main parts: the general info/metadata, the paths, and the models.

General info/metadata

This contains some of the descriptive information for the API overall, like where you can find licensing information, or who to contact for help.

Paths

These describe the individual endpoints (or URL paths) for the API. It describes what kind of HTTP request to make, how it should be authorized, and what kind of information you should add to the request, and what you should expect to get back. In the example below, you can see that it is a POST request, There are a couple required parameters in the URL, another one in the body, and you get back a CreateRefundResponse.

Models

The models describe the different objects that the API interacts with. They are used primarily for serializing the JSON response from the API into native objects for each language. In this one, CreateRefundResponse, you can see it has a couple other models that it is comprised of, as well as a description and even an example of what the response looks like.

You can see the most recent version of our specification to date version in the Connect-API-Specification repo on GitHub.

The specification is an important part of our generation process, as it is the source of truth about how our APIs work. When other teams want to expand their APIs, release new APIs, or just increase the clarity of a model description, they can make a edit to this single file and have their changes propagate to all of the client SDKs. We actually generate most of our specification from the files that describe the internal service to service communication for even more process automation.

swagger-codegen

Now that we have the specification for our APIs ready to go, how do we turn it into a client facing SDK? The answer is swagger-codegen. Swagger-codgen is an open source project that applies your Open API specification to a series of templates for SDKs in different languages. Because the swagger-codegen project is so active, we actually check in a copy of our template files for each of our supported SDKS, and pin to specific swagger-codegen versions to make sure that we don’t accidentally push breaking changes to our users as a result of all the automation. You can see the templates that power the {Java, PHP, C#, Python, Ruby} SDKs in the same repository as our specification file: Connect-API-Specification. Generating SDKs for all of these languages, however was still a long manual process.

Travis CI to the rescue

That isn’t good enough for when multiple internal teams are releasing updates and making changes concurrently. Luckily, Travis CI can help us out. In addition the the Connect-API-Specification repository, we also have separate repositories for each of our supported SDK languages (like https://github.com/square/connect-php-sdk for PHP). We’ve set up Travis CI for the Connect-API-Specification repository to automatically build the SDKs using the specification file and templates that we have checked in. We first install swagger-codegen to the travis machine, generate the SDKs, and then use an encrypted set of keys to push those new SDKs to the appropriate GitHub repository. The best part of using Travis CI is that all of it is public — you can see exactly what goes on in our travis.yml file and associated folder of scripts. Don’t hesitate to submit a PR if you think there is something we could be doing better!

Hope your enjoyed the look into our SDK generation process. You can also see a recorded talk I gave at DevRelCon about the subject here. If you want to learn more about our SDKs, or other technical aspects of Square, be sure to follow on this blog and our Twitter account!