It's just a compilation of other materials that I combined around the internet.
I've copied the image this from this article
Multiple Hosts
OpenAPI 2.0 allowed specifying a single host
and basePath
, and yet the schemes attribute allows specifying both http and https, therefore effectively enabling two hosts that only vary in the scheme. In the OpenAPI.vNext, the working branch of the spec repo, a new root level hosts object contains an array of objects that contain host
, basePath
, and scheme properties
.
By structuring this as an array of objects, any number of root URLs for the API can be supported, and it allows for a clearer correlation of the scheme, host, and basePath properties. It also reduces the number of root level properties required, simplifying the document structure.
Additionally, the host
, basePath
, and scheme
may be overriden at the path item level. This should make it easier to incorporate functionality provided on a separate host into an API description.
URL Structure
Currently, Swagger 2 lets you define schemes
, a host
and a baseUrl
, which is 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 OpenAPI 3, this was only allowed in the actual endpoint URLs. You define the templates with a variable
property.
Swagger 2
info:
title: Swagger Sample App
host: example.com
basePath: /v1
schemes: ['http', 'https']
OpenAPI 3
servers:
- url: https://{subdomain}.site.com/{version}
description: The main prod server
variables:
subdomain:
default: production
version:
enum:
- v1
- v2
default: v2
There’s a few minor changes to path items, too. They now can accept a description. Also you can now give each path its own base URL (http://login.example.com, for example).
URL verbs
You’re no longer allowed to define a request body for GET and DELETE (which matches how RESTful APIs work). Lastly, there's support for TRACE.
Components
Swagger 2 had the concept of definitions, however they were somewhat arbitrary and weren’t as well-defined. OpenAPI 3 attempts to standardize the concept into components
, which are definable objects that can be reused multiple places.
Open API spec 3.0 provides components object which can contain:
- schemas
- parameters
- responses
- examples
- security schemes
- links
- request bodies
- headers
- callbacks
This component object won’t affect the API until it is referenced somewhere in the API.
Advantage : If multiple operations of an API needs similar input structure the the input structure can be defined under component as request bodies and can be reused in multiple paths. Similarly headers, responses and so on can be reused.
"components": {
"schemas": {
"Category": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"Tag": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
}
},
"parameters": {
"skipParam": {
"name": "skip",
"in": "query",
"description": "number of items to skip",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
},
"limitParam": {
"name": "limit",
"in": "query",
"description": "max records to return",
"required": true,
"schema" : {
"type": "integer",
"format": "int32"
}
}
},
"responses": {
"NotFound": {
"description": "Entity not found."
},
"IllegalInput": {
"description": "Illegal input for operation."
},
"GeneralError": {
"description": "General Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GeneralError"
}
}
}
}
}
}
Request format
One of the most confusing aspects of Swagger 2 was body/formData
. They were a subset of parameters—you could only have one or the other—and if you went with body, the format was different than the rest of the parameters. (You could only have on body parameter, the name was irrelevant, the format was different, etc.)
Now, 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).
Swagger 2
"/pets/{petId}":
post:
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
type: string
- name: user
in: body
description: user to add to the system
required: true
schema:
type: array
items:
type: string
OpenAPI 3
"/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 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
.
Request body content negotiation
The 3.0 release features a requestBody that supports content negotiation so that you can define different schemas and examples for various media types. The requestBody allows web services to accept and return data in different formats, such as images, plain text, XML, and JSON. It also allows you to provide one or multiple examples.
Examples
The requestBody has a lot of new features. You can now provide an example (or array of examples) for requestBody. This is pretty flexible (you can pass in a full example, a reference, or even a URL to the example).
Linking
Linking is one of the most interesting additions to OpenAPI 3. It’s a bit complicated, but potentially incredibly powerful. It’s 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'
See what’s happening there? 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 usecase 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.
To this end, the 3.0 draft specification introduces the links object in order to describe which new resources may be accessed based on the information retrieved from an initial resource. This is not necessarily hypermedia-driven in that, the URLs to the new resources have not been embedded in the returned payload, but they are constructed based on rules defined in OpenAPI Specification. A new expression syntax has been introduced to allow information from a response to be correlated with parameters in the linked operation.
Security
A bunch of changes to security! It’s been renamed, OAuth2 flow names have been updated, you can have multiple flows, and there’s support for OpenID Connect. The basic
type has been renamed to http
, and now security can have a scheme
and a bearerFormat
.
Swagger 2
securityDefinitions:
UserSecurity:
type: basic
APIKey:
type: apiKey
name: Authorization
in: header
security:
- UserSecurity: []
- APIKey: []
OpenAPI 3
components:
securitySchemes:
UserSecurity:
type: http
scheme: basic
APIKey:
type: http
scheme: bearer
bearerFormat: TOKEN
security:
- UserSecurity: []
- APIKey: []
Callbacks
Webhooks leverage HTTP in an publish/subscribe pattern, and they have become a popular pattern among API providers, including Slack, GitHub, and many other popular services. Webhooks are simple to use and fit nicely into an existing HTTP-based style of API. However, one criticism of the OpenAPI spec was that it had no way to describe an outbound HTTP request and its expected response. The new callback object makes this possible. A callback object can be attached to a subscribe operation in order to describe an outbound operation that a subscriber may expect.
JSON Schema
A number of requests were made to expand the subset of JSON Schema that the OpenAPI spec allows to include more complex features of JSON Schema. In the 2.0 spec process, the potential tooling complexities around code generation prompted the exclusion of anyOf and oneOf. However, many users have requested relaxing that constraint, even though it would compromise tooling support for those features. This is one of the great challenges in spec design, and it is never easy when making choices like this to know whether it is better to give people sharp tools that they could cut themselves with, or to rely on experience to say no, the burden of this responsibility is too great. While OpenAPI 2.0 took the more conservative approach, the user base has grown more experienced, so some of the restrictions are being lifted, and users will have to make smart choices.
Type Can Now Be An Array
In previous versions of OpenAPI, type could only be a single string. But in JSON Schema, type can be an array of strings. There is no workaround for this in version 2.0, but in version 3.0, you can select multiple types using oneOf:
oneOf:
- type: string
- type: integer
With OpenAPI 3.1, the specification now supports type as an array:
type: [string, integer]
Nullable is No More
Neither OpenAPI 2.0 nor 3.0 support null as a type, but JSON Schema does support type null. OpenAPI 3.0 includes the field name nullable, which you can set to true if you want the value to be null:
type: string
nullable: true
However, support for type null has been added in version 3.1, and nullable has been removed.
type: [string, "null"]
Top comments (0)