6 Most Significant Changes in OAS 3.0

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.

Swagger 2.0 VS OpenAPI 3.0

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).

Server Object Specification

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

Response 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.

Link Object Specification

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.

Callback Object Specification

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.

Example Object Specification

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.

Guy Levin

Read more posts by this author.

comments powered by Disqus

Subscribe to REST API and Beyond

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!