The OpenAPI Spec, formerly known as Swagger has announced the release of Open API Specification 3.0. This is a very important milestone, but it is also the first major release since the specification was entered into the Linux Foundation. The OpenAPI Specification (OAS) is supported by various industry heavyweights including the likes of Google, Microsoft, and IBM.
Swagger was created by Tony Tam (from Wordnik) in 2010. The swagger project was acquired by SmartBear in 2015 and eventually, the company donated the specification to the newly formed OpenAPI Initiative (OAI) which is part of the Linux Foundation.
Version 3.0 of the API specification format has taken a much more modular, and reusable approach to defining the surface area of an API, enabling more power and versatility when it comes to describing the request and response models, as well as providing details on the common components that make up API usage like the underlying data schema and security definitions.
There are numerous changes to the API specification, but there is just a handful that will have a significant impact across every stop along the API life cycle where API definitions are making an impact.
1. Server (Hosts)
When describing your API, you can now provide multiple hosts, allowing you to better deal with the complexity of how APIs might be located in a single location or spread across multiple cloud location, and global infrastructure.
Currently, Swagger 2 lets you define schemes
, a host
, and a baseUrl
, which are combined into your URL. Now, you can have multiple URLs
, and they can be defined anywhere (meaning you can have just one at the base like before, or a specific endpoint can have its own server if the base URL is different).
Additionally, path templating is now allowed. In OAS 3.0, this was only allowed in the actual endpoint URLs.
You define the templates with a variable
property.
For example in OAS 3.0:
servers:
- url: https://{subdomain}.site.com/{version}
description: The main prod server
variables:
subdomain:
default: production
version:
enum:
- v1
- v2
default: v2
There are a few minor changes to path
items, too. They now can accept a description, and there's support for TRACE
. Thanks to servers
, you can now give each path their own base URL.
Lastly, you’re no longer allowed to define a request body for GET
and DELETE
(which matches how RESTful APIs work).
2. Components
The new components
architecture really reflects APIs, making everything very modular, reusable, and much more coherent and functional. The new version encourages good schema and component reuse, helping further bringing the definition into focus.
Swagger 2 had the concept of definitions, however, they were somewhat arbitrary and weren’t as well-defined. OpenAPI 3.0 attempts to standardize the concept into components
, which are definable objects that can be reused multiple places.
So, what components there are in OAS 3.0, here’s the list:
- responses (existing)
- parameters (existing)
- examples (new)
- requestBodies (new)
- headers (new)
- links (new)
- callbacks (new)
- schemas (updated)
- securitySchemes (updated)
So, rather than one definitions
section with all references, you would now access something like #/components/schemas/Pet
.
Components Object Specification
3. Body
The latest version of the specification plays catch-up when it comes to allowing the body
of a request
and response
to be defined separately from the request parameters, allowing for more control over the payload of any API calls.
Body
has been moved into its own section called requestBody
, and formData
has been merged into it. In addition, cookies
has been added as a parameter type (in addition to the existing header, path and query options).
"/pets/{petId}":
post:
requestBody:
description: user to add to the system
required: true
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
examples:
- name: Fluffy
petType: Cat
- http://example.com/pet.json
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
type: string
The requestBody
has a lot of new features. You can now provide an example (or array of examples) for requestBody. The new requestBody
supports different media types (content is an array of mimetypes
, like application/json
or text/plain
, although you can use */*
as a catch-all!).
For parameters, you have two options on how you want to define them. You can define a schema
(like in 2.0), which lets you describe the item. Or, if it’s more complex, you can use content
, which is the same as requestBody
.
Responses have also gotten an upgrade!
Wildcard response codes mean you can now define a response
for 4xx
rather than having to define each one separately.
Responses and responses headers can both be more complex. You can use content
objects (like in requests) for the payload.
There’s also the concept of callbacks
, which allow you to define a webhook
:
sampleWebhook:
'$request.body#/url':
post:
requestBody:
description: Callback payload
content:
'application/json':
schema:
$ref: '#/components/schemas/SomePayload'
responses:
200:
description: webhook processed!
Request Body Object Specification
4. Linking
While not quite full hypermedia, version 3.0 of the OpenAPI Spec supports linking, allowing for the description of relationships between paths, giving a nod towards hypermedia design pattern, making this version the most resilient so far.
Linking is basically a way of describing “what’s next”. (For people familiar, it's in the same vein as HATEOAS / Hypermedia APIs.)
Let’s say you get a user, and it has an addressId
. This addressId
is pretty useless by itself. You can use links to show how to “expand” that, and get the full address.
paths:
/users/{userId}:
get:
responses:
200:
links:
address:
operationId: getAddressWithAddressId
parameters:
addressId: '$response.body#/addressId'
In the response from /users/{userId}
, we get back an addressId
. The links
describes how we can get an address by referencing the $response.body#/addressId
.
Another use-case is pagination. If you fetch 100 results, links
can show how to get results 101-200. It’s flexible, which means it can handle any pagination scheme from limits
to cursors
.
5. Callbacks (Webhooks)
Like the nod towards hypermedia, the specification now allows for the inclusion of callbacks that can be attached to a subscription operation describing an outbound operation--providing much needed webhook descriptions as part of API operations, making it much more real time and event driven.
The majority of API providers and consumers are acutely aware of the fact that APIs are increasingly implementing mechanisms to establish two-way communication, in the style of publish/subscribe patterns and technologies such as WebSockets.
OAS acknowledges this fact by introducing the Callback object that provides a means to define a webhook in an API specification.
The Callback
object can be defined per parent operation, allowing a great deal of flexibility in the data a given callback can carry. Moreover, a Callbacks
object is also provided that allows a map of callbacks to be defined.
6. Examples
The new version enables API architects to better describe, and provide examples of APIs responses and requests, helping make API integration a learning experience, by providing examples for use beyond just documentation descriptions.
The examples object can now be used to describe any kind of example rather than one encoded in JSON or YAML; other formats such as XML or plain text can be expressed in JSON string.
Describing an XML example can be done as follows:
examples:
- '<Example><Subject>ABC</Subject></Example>'
The example can also be externalized by using a $ref
object and be leveraged by Content
objects.
Summary
These 6 are the most significant changes to the OpenAPI Spec 3.0, at least from my point of view. I believe that it is a giant step forward in terms of REST API Definitions. I believe that with the support of visual API editor tools like ApiBldr, when this tool will also support OAS 3.0, it will easy the use of the new specifications even for non-developers \ with not much technical knowledge.
One more thing to note about OAS 3.0 is the increased investment in JSON Schema, including the support of oneOf
, anyOf
, nullable
, deprecated
, writeOnly
and not
functions, allowing for alternative schema, as well as the standard JSON schema definition included.
Today, OAS is the clear leader of the API definition formats, with the largest adoption, as well as the amount of tooling developed.
While documentation and SDK generation are still the top two reasons for crafting API definitions, there are numerous other reasons for using API definitions including mocking, testing, monitoring and much, much more.
It is clear that the 3.0 version of the specification has considered the design patterns across a large number of implementations, providing a pretty wide reaching specification for defining what an API does. The improvement in the objects the specification offers are exceeding valuable in simplifying the means to create definitions that can be reused throughout an API specification.
Thanks to Gregory Koberger and his great blog post: A Visual Guide to What's New in Swagger 3.0 that was used as the basis for this article.