Embracing OpenAPI (Swagger) at Box

This post was written by Karthik Shanmugasundaram, Senior Software Engineer on the Developer Ecosystem team at Box.

Over the past few years, OpenAPI (formerly known as Swagger) has become one of the world’s most popular API frameworks. The OpenAPI specification provides API consumers, both humans and machines, with an easy way to comprehend and consume an API and API service providers with a standardized way to design, build, and document RESTful APIs. The OpenAPI specification is defined and maintained by the OpenAPI Initiative, a consortium of technology companies that work to create, evolve, and promote a vendor-neutral, language-agnostic API description format based on the Swagger specification.

Today, we’re excited to share the first iteration of the Box OpenAPI specification for interacting with the Box Content API.

At Box, we benefit from the OpenAPI specification in two ways. First, we’re able to define a standard, language-agnostic interface for third-party developers to interact with the Box Content API. Second, the OpenAPI specification allows us to create “API contracts” between engineering teams at Box for the various microservices built within Box.

In this blog post, I’ll discuss these different uses of Open API specification at Box.

If you’re in the San Francisco area, you can also attend the Cloud Elements API Talk on May 23rd featuring Ken Yagen, VP of Platform Product at Box, about how we use the OpenAPI specification. You can learn more about the event here.

Interfacing with the Box Content API with OpenAPI 2.0

The Box Content API gives developers access to a set of cloud-based content management capabilities for use in their apps, such as secure file storage, preview, search, commenting, metadata, and more, as well as a way to integrate apps and services with Box. It is RESTful and it is organized around the main resources from the Box web interface. The Box Content APIs are exposed in four different endpoints: authorization, access tokens, upload, and v2 API (which contains all the other features of the Box Platform).

We’ve created OpenAPI JSON files for each of these endpoints:

Establishing the Definition Model

The requests and responses of Box Content API do not strictly following the single resource model. When the OpenAPI JSON is reverse-engineered from the existing Box Content API, the resources are created as model definitions. Each resource is an aggregation of smaller reusable models. Using the “allOf” property, the smaller models are aggregated to generate the resource models. Most of the API responses return the resource models. In some older APIs, API-specific responses are returned which are not resources. These responses are created as definitions in the OpenAPI specification.

Generating Client Libraries for the Box Content API

One of the benefits of the OpenAPI specification is that it allows you to generate client lirbaries to interact with an API in your preferred language. You can generate client libraries with an OpenAPI specification with a variety of tools that cover many different development languages. For popular languages, we suggest the open source Swagger Codegen project, which is actively maintained by the developer community. Due to that, we suggest you to check out the source code from git. For example, troubleshooting section provides possible work arounds for Java and Node.js.

The Github repo for Box OpenAPI 2.0 specification can be cloned using the following command:

git clone https://github.com/box/box-openapi.git

The documentation for the API usage for the language in which the client is generated can be found in the ‘docs’ sub folder of the output folder. For example, to get information of a file using a Node.js client, the following code snippet is generated as part of the documentation.

```javascript
var Box20Api = require(‘box_20_api’);
var defaultClient = Box20Api.ApiClient.default;
// Configure OAuth2 access token for authorization: OAuth2Security
var OAuth2Security = defaultClient.authentications[‘OAuth2Security’];
OAuth2Security.accessToken = ‘YOUR ACCESS TOKEN’;
var apiInstance = new Box20Api.FilesApi();
var FILE_ID = “FILE_ID_example”; // String |
var opts = {
‘fields’: “fields_example” // String | Attribute(s) to include in the response.
};
var callback = function(error, data, response) {
if (error) {
console.error(error);
} else {
console.log(‘API called successfully. Returned data: ‘ + data);
}
};
apiInstance.getFile(FILE_ID, opts, callback);
```

Visualizing and Interacting with the Box Content API using UI Tools

The Box OpenAPI specification JSON files can be given to any OpenAPI specification-compliant tools, such as Swagger UI or API Studio. These tools provide a standard visual interface for the API and allow you to interact with its resources.

Creating an App in the Box Developer Console

To access the Box Content API using the OpenAPI specification, you must first create an app in the Box Developer Console. Once you’ve created an app, you can grab a Developer Token, which allows use to interact with the API. You can find a button to generate a Developer Token in the Configuration settings for your app in the Box Developer Console.

Generate a Developer Token in the Box Developer Console

Next, scroll down to the CORS Domain section of your app’s Configuration settings in the Box Developer Console and add the domain URL for your preferred UI Tool in the Allowed Origins. In this case, I’ll use API Studio, so I’ll add “http://playground.apistudio.io" to the Allowed Origins section.

Add http://playground.apistudio.io to the Allowed Origins section of the Box Developer Console configuration

Here’s how you can get started with API Studio and the Box Content API.

Import the Box OpenAPI JSON File to API Studio
  • In the Security section, click the “Authenticate” button. It opens a pop-up.
OAuth 2.0 Authentication Pop Up
  • Provide the Developer Token created in the previous section and click “Authenticate.”
Provide a Developer Token generated in the Box Developer Console
  • Try a command, such as GET /files/{file_id} operation by providing a file_id and fields. “Fields” is a comma separate list of fields that needs to be returned as part of the result.
  • If you try POST or PUT calls, the ‘Send Request’ might be disabled. To enable it, right click on top of the button. Click ‘Inspect’. It opens up the HTML source code.
  • Remove the attribute ‘disabled=”disabled”’ from the button element.
  • Now, the ‘Send Request’ is enabled for that operation.

Creating Microservices at Box

Beyond providing third-party developers with an easy way to learn and interact with the Box Content API, we also use the OpenAPI specification in our own internal development process at Box. Various engineering teams at Box building microservices use the OpenAPI to create “API Contracts” between teams. These API Contracts standardize how APIs are developed and provide a simple way for teams to understand and communicate their APIs with other engineering teams. Once the API Contract is finalized, the OpenAPI JSON files are used to auto-generate the server stubs. Also, the consumers of the API auto-generate the clients using the OpenAPI JSON files. All the OpenAPI-based APIs are going through the same gateway, which helps monitoring the requests.

Some of the key reports that are generated are based on the following:

  • End point
  • Operation
  • Event type
  • Status code of the response

Extensions & Customization

  • Each microservice has its own OpenAPI JSON file. During the build time, all the JSON files are combined in to a single OpenAPI JSON file.
  • Box built a custom API Contract Validation Tool as internal OpenAPI specification uses fields like ‘discriminator’ for inheritance etc.
  • Extended OpenAPI PHP code generation to support the internal needs.

Monitoring & Testing the Box Content API

Additionally, the Box OpenAPI specification allows to easily monitor and test our API endpoints. We use Runscope to import the OpenAPI JSON files and create tests instantly. The API can be monitored by running the tests whatever intervals and we can create tests to maintain the integrity of our API. Alerts and notifications from Runscope can be sent to Slack or Pagerduty immediately, alleviating the need to build and maintain our own testing services.

We’d love to hear your thoughts about the Box OpenAPI specification or about your experience with OpenAPI. You can leave a comment below or reach out to us on Twitter.

Don’t forget, we’ll be at the Cloud Elements API Talks in San Francisco next week talking about our use of OpenAPI. You can register here.