Mike Mackrory is a guest contributor for the Runscope blog. If you're interested in sharing your knowledge with our readers, we would love to have you! Please fill out this short form and we'll get in touch with you.
Update: Part two of this OpenAPI series is out now! Check it out here.
When I’m not writing articles, I work for a large software organization. We have lots of engineering teams, all of which contribute to specific elements of a sophisticated, versatile and highly available commerce platform. We’ve chosen an API-First approach to accelerate development and enhance collaboration between domains.
Because APIs are so central to how our software runs, documenting our APIs is essential for making sure that everyone across our large IT organization understands what is going on. That’s why we use OpenAPI to help document API specifications.
In this article, I’m going to introduce you to the OpenAPI specification and API-First development principles. In a subsequent article, I’ll describe how our teams use the API-First approach to support our engineering endeavors.
The OpenAPI Specification
The OpenAPI specification began life as the Swagger specification. The OpenAPI Initiative owns the specification (after it was donated), following several years of development from companies such as Reverb Technologies and SmartBear. The OpenAPI Initiative hosts the community-driven specification on GitHub.
The specification is a language agnostic format which is used to describe RESTful web services. The resulting files can be interpreted by applications to generate code, produce documentation and create virtual simulations of the services they describe.
What is API-First Development?
The evolution of applications into the cloud environment opens opportunities for greater integration of services and increased code reuse. Having an interface through which other services’ applications can interact with your application is an integral step in exposing your functionality to others. However, developing an API shouldn’t be something you do to expose functionality after it’s developed.
Your API document should be the foundation upon which you build an application. This principle is precisely what API-First development is all about. You design and create documentation which describes interactions between your new service and the outside world, and once you have that established, you develop the logic to support those interactions. Let’s look at the benefits afforded by such an approach.
How API-First Benefits Your Organization
When your organization begins with API documentation, this allows teams to start interacting with each other sooner in the development process. The API document is a contract between your application and those who use it.
Internal development can take place behind the API contract without interfering with the efforts of those who use it. Teams that plan on consuming your application can use the API specifications to understand how to interact with your application, even before development begins. They can also use the document to create virtual services with which to test their application.
Anatomy of an OpenAPI Document
The current version of the specification is version 3.0.1, and it is thoroughly documented in the OpenAPI GitHub repository. If you’re like me, though, I much prefer looking at an example of a specification over working my way through specification documents describing each possible part in explicit technical detail.
Let’s look at a simple API document that describes the API for a service, which allows a user to create, modify, retrieve and delete a user preference. You can view this API in its entirety on SwaggerHub.
An OpenAPI document has three required sections or objects:
openapi - Semantic version number of the OpenAPI Specification version
info - Metadata about the API
paths - Available paths and operations for the API
You can include additional objects as needed. Other objects include security, servers, tags, and components.
OpenAPI and Info Objects
openapi: 3.0.1 info: version: "1.0.0" title: User Preference API description: This is an to support the creation, modification, retrieval and deletion of a User Preference.
The openapi object states the version of the specification used for the document. The version is essential for users to understand how the document is structured, and more importantly, for any tooling which may ingest the document for purposes of validation, or to create virtual services, among other reasons.
The info object provides essential information about the API itself. The title and version are required fields, and we have the option to include additional information such as a description and contact and licensing information.
The paths object is the heart of the API document. This object details the paths available to interact with the application, what methods are available, and the details of what those interactions include. This object includes request parameters and expected outcomes:
paths: /preference: get: summary: Find preference by ID description: Returns user preference operationId: getPreferenceById parameters: - name: id in: query description: ID of preference to return required: true schema: type: string responses: '200': description: Successful request content: application/json: schema: $ref: '#/components/schemas/Preference' '400': description: Invalid ID supplied '404': description: User Preference not found
The excerpt above describes the path for a GET request to retrieve a user preference by ID. The properties are mostly self-explanatory. Of note is the schema for the HTTP 200 response. The $ref property references an object elsewhere in the file. In this case, it’s a schema description which is used for multiple path descriptions:
components: schemas: Preference: type: object required: - userId - preferenceName - status properties: userId: type: string format: uuid preferenceName: type: string preferenceValue: type: string status: type: string description: Preference Status enum: - test - enabled - disabled - delete
Defining components in one place and referencing from those objects that use it allows us to reuse the same definition and make our OpenAPI contract more manageable.
One of the best ways to learn any new technology or specification is by using it for your projects. I have found the editor available on SwaggerHub to be especially useful, mainly when I use the provided templates as a base, and pair them with the specification.
As I mentioned at the beginning of this article, starting with API documentation is an essential step for anyone developing applications in the cloud. As an engineer, it can be tough to start with documentation rather than diving right into the code, but spending time crafting and refining your API before development starts yields exponential benefits over time.
Check out part 2 of this series where we talk more about the lessons learned when using OpenAPI as a team.