What are the differences between OpenAPI 2.0 and 3.0? #
The OpenAPI Specification (OAS) has emerged as a powerful tool in creating a standardized and language-agnostic interface to RESTful APIs. As you may know, OpenAPI 2.0, formerly known as Swagger, laid the groundwork for modern API documentation, providing clear guidelines for describing, producing, consuming, and visualizing RESTful web services. The leap to OpenAPI 3.0, however, brought substantial revisions, refinements, and new features that significantly enhanced its capabilities. In this article, we explore the primary differences between OpenAPI 2.0 (Swagger) and OpenAPI 3.0 to help you navigate the transition and understand the enhancements.
Table of Contents #
- Schema Handling
- API Paths and Operations
- Security Definitions
- Request Bodies
- Responses
- Components
- Links
- Callbacks
- Examples
- Miscellaneous Changes
- Conclusion
Schema Handling #
Data Types and Formats #
One of the key changes in OpenAPI 3.0 is the broader and more flexible handling of data types and formats. OpenAPI 3.0 extends JSON Schema to offer more comprehensive ways to define data structures.
OpenAPI 2.0:
type: integer
format: int32
OpenAPI 3.0:
type: integer
format: int32
The difference lies in the extent of JSON Schema support; OpenAPI 3.0 expects JSON Schema to handle definitions, underpinning almost every element that describes data.
Nullable Properties #
In OpenAPI 2.0, the way to showcase that a value could be null
was less direct, often resulting in workaround solutions. OpenAPI 3.0 introduces a nullable
property for more clarity.
OpenAPI 2.0: (with workaround)
type: object
properties:
name:
type: string
x-nullable: true
OpenAPI 3.0:
type: object
properties:
name:
type: string
nullable: true
API Paths and Operations #
Path Parameters #
The way path parameters are defined remains similar between the two versions, but OpenAPI 3.0 offers greater flexibility.
OpenAPI 2.0:
paths:
/users/{userId}:
parameters:
- name: userId
in: path
required: true
type: string
OpenAPI 3.0:
paths:
/users/{userId}:
parameters:
- name: userId
in: path
required: true
schema:
type: string
The notable change here is the replacement of the type
field with a schema
object, adhering to a more consistent schema definition system.
Security Definitions #
In OpenAPI 2.0, security definitions were managed globally, with limited flexibility. OpenAPI 3.0 advances these features by providing more refined controls.
OpenAPI 2.0:
securityDefinitions:
api_key:
type: apiKey
name: api_key
in: header
petstore_auth:
type: oauth2
authorizationUrl: https://petstore.swagger.io/oauth/authorize
flow: implicit
OpenAPI 3.0:
components:
securitySchemes:
api_key:
type: apiKey
name: api_key
in: header
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: https://petstore.swagger.io/oauth/authorize
scopes:
write:pets: modify pets in your account
The securityDefinitions
object was replaced by components.securitySchemes
, expanding the capabilities for defining and managing security.
Request Bodies #
Arguably one of the most significant changes is how OpenAPI 3.0 handles request bodies. OpenAPI 2.0 used parameters
to manage all data inputs, including body content and form data.
OpenAPI 2.0:
paths:
/pets:
post:
parameters:
- in: body
name: pet
required: true
schema:
$ref: '#/definitions/Pet'
OpenAPI 3.0:
paths:
/pets:
post:
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
In OpenAPI 3.0, the introduction of the requestBody
object offers a clearer and more structured way to define body content, aligning it with specific media types.
Responses #
The response structure in OpenAPI 3.0 offers more granularity in defining responses for different content types. While the core principles remain the same, subtle improvements offer better readability and manageability.
OpenAPI 2.0:
paths:
/pets:
post:
responses:
200:
description: Successful operation
schema:
type: array
items:
$ref: '#/definitions/Pet'
OpenAPI 3.0:
paths:
/pets:
post:
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
OpenAPI 3.0 makes use of the content
object, allowing descriptions and content types to be more explicitly defined.
Components #
The introduction of the components
object in OpenAPI 3.0 consolidates reusable components such as schemas, responses, parameters, examples, and security definitions.
OpenAPI 3.0:
components:
schemas:
Pet:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
responses:
NotFound:
description: Resource not found
This reorganization enhances modularity and the maintainability of API documentation by allowing more reusable pieces.
Links #
Links in OpenAPI 3.0 allow for better description of relationships between operations, bringing more contextual overview and navigational clarity.
paths:
/users/{userId}:
get:
summary: Get a user by ID
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/User'
links:
address:
operationId: getUserAddress
parameters:
userId: $response.body#/id
Links provide the ability to describe dynamic links between operations, improving API discoverability and usability.
Callbacks #
One of the more sophisticated features in OpenAPI 3.0 is the support for callbacks, enabling the specification of asynchronous operations.
paths:
/subscribe:
post:
summary: Subscribe to event notifications
requestBody:
content:
application/json:
schema:
type: object
properties:
callbackUrl:
type: string
responses:
'201':
description: Subscription created
callbacks:
callbackEvent:
'{$request.body#/callbackUrl}':
post:
requestBody:
description: Callback payload
content:
application/json:
schema:
type: object
properties:
eventId:
type: string
responses:
'200':
description: OK
This allows developers to capture client-defined callback URLs, enhancing support for webhook-like scenarios.
Examples #
Both specifications support examples, but OpenAPI 3.0 provides more structure and flexibility with the introduction of the examples
keyword within the content
object.
OpenAPI 3.0:
paths:
/user:
get:
responses:
'200':
description: A user object
content:
application/json:
schema:
$ref: '#/components/schemas/User'
examples:
user:
summary: A user example
value: {
"name": "John Doe",
"id": 123
}
This allows for multiple examples and better documentation of different use cases or scenarios.
Miscellaneous Changes #
Tags and Operation IDs #
Tags and operation IDs in OpenAPI 3.0 have become more versatile, offering better ways to describe and organize APIs.
Improved Descriptions #
Descriptions can now be placed in multiple fields across the specification, offering more detailed documentation.
Deprecation #
Operations and parameters can now be deprecated explicitly with the deprecated
keyword.
paths:
/pet:
get:
deprecated: true
Rewrite of Other Elements #
Other elements such as headers, form data, and parameter serialization rules have also been revised for better consistency and structure.
Conclusion #
The transition from OpenAPI 2.0 to 3.0 introduced pivotal changes that streamlined API descriptions and enhanced the flexibility, verbosity, and structure of API documentation. By adopting OpenAPI 3.0, developers can leverage improved features for schema handling, request and response management, linking operations, and asynchronous callbacks.
For further reading and reference, check out the OpenAPI Initiative and the OpenAPI Spec Documentation.
Adopting these changes can go a long way in ensuring your APIs are well-documented, standardized, and ready for comprehensive integration.
If you enjoyed this article, feel free to share it or check out more resources to boost your API development and documentation skills.