
Kin Lane, theAPI Evangelist, recently got in touch asking whether I had a good example of an OpenAPI 3.0.0 definition.
As part ofswagger2openapi I keep up to date a conversion of the ubiquitous SwaggerPetstore example API definition, and some 3.0.0examples have recently been added to theOpenAPI specification repository, but we we both agreed I should look for something real-world which would show off the major changes between OpenAPI 2.0 (fka Swagger) and OpenAPI 3.0.0.
I turned out to be harder than I expected to find a good candidate definition, even as the maintainer of theAPIs.guru collection which contains over 500 real-world APIs.
I set myself some ground rules:
- The definition had to originate in Swagger 2.0 format
- It had to be valid at source, not patched up as many APIs in APIs.guru are
- It should include oAuth authentication
- It must have
body
orformData
parameters - It must have
query
orpath
parameters
Luckily I have the metadata of all of the APIs.guru APIs extracted into a database for easy analysis. If I couldn't find an example in APIs.guru, I could always widen the search to include the 45,000-plus APIs I've indexed from GitHub andSwaggerHub.
I needed to add a couple of columns to the API metadata table, then I queried using my constraints, and ordered by size to find the most concise candidate definition.
The eventual winner was theAuthentiq.Io API as mentioned on Kin'sblog posting.
So, let's get stuck in, and start looking at the diff between theSwagger 2.0 original, and theconverted OpenAPI 3.0.0 definition.
Metadata
-swagger: '2.0'+openapi: 3.0.0-RC1
First things first, and we get our feet wet gently. All references to Swagger in the OpenAPI specification have been changed to OpenAPI, and that includes theswagger
property in your API definition.
While the version number is still a string, it is nowsemver - major.minor.patch - compatible. This means when the OpenAPI 3.0.0 specification is released, patch versions can be published to clarify wording, examples etc where this does not affect the specification itself, and minor versions can be published which add new features in a backwards-compatible way. Only breaking changes would result in an OpenAPI 4.x.x version.
Any characters after the patch version are informative only and should be ignored by tooling. In fact, tooling authors should look only at the major and minor (e.g. 3.0) versions when determining compatibility.
One other change to theinfo
object is thattermsOfService
must now be a URL. This should not affect many APIs as this appears to always have been standard practice.
API endpoint definition
-host: connect.authentiq.io-basePath: /-schemes:- - https+servers:+ - url: 'https://connect.authentiq.io/'
Out go separatehost
,basePath
andschemes
and in comes an array ofservers
each with aurl
property, allowing multiple endpoints for an API. Unlike Swagger 2.0, OpenAPI 3 also supportsurl templating, by means of replaceablevariables
(not shown here as they will not exist in converted definitions).
Content-Types
-consumes:- - application/x-www-form-urlencoded- - application/json-produces:- - application/x-www-form-urlencoded- - application/json- - application/problem+json- - text/html
Out go the top-levelconsumes
andproduces
arrays. As we will see later, eachrequestBody
andresponse
can now specify multiple content-types.
Query and Path Parameters
parameters: - name: client_id in: query- type: string description: > A client ID obtained from the [Dashboard](https://dashboard.authentiq.com/). required: true+ schema:+ type: string
parameters
andheaders
are no-longer objects which share properties liketype
anditems
withschema
objects, instead they include one.parameters
andheaders
can optionally have acontent
object instead of aschema
if their definition varies based oncontent-type
.
parameters
are the one area I've found where it is not possible to losslessly convert valid Swagger 2.0 definitions to OpenAPI 3.0. Thearray
collectionFormat
oftsv
(tab-separated values) has been dropped, and it is no longer possible to define nested separators for arrays within arrays, e.g.a|b,c|d
. If you need these features, now would be a great time to raisean issue at the OpenAPI specification repository.
FormData parameters
parameters: - name: Authorization in: header description: | HTTP Basic authorization header. required: false- type: string- - name: client_id- in: formData- description: |- The registered client ID.- required: true- type: string
This is where it gets interesting, allparameters
which arein: formData
disappear. We'll see them turn up again in a new guise shortly. The same would be true for thebody
parameter.
Reference Objects
responses: '200':- $ref: '#/responses/Token'+ $ref: '#/components/responses/Token'
This is an example of the restucturing that has gone on in OpenAPI 3.0.0. Schemas from/definitions
now reside under/components/schemas
and the top-levelresponses
object moves to/components/responses
- all$ref
s need to be updated to maintain the referential integrity of your definition.
RequestBodies
+ requestBody:+ content:+ application/x-www-form-urlencoded:+ schema:+ type: object+ properties:+ client_id:+ description: |+ The registered client ID.+ type: string+ client_secret:+ description: |+ The registered client ID secret.+ type: string+ format: password
Here we see the previousformData
parameters have been converted into properties of a new object held under therequestBody
property of theoperation
object.
Theconsumes
array values become the keys of thecontent
object map.
Responses
responses: '200': description: A list of Client Objects.- schema:- type: array- items:- $ref: '#/definitions/Client'+ content:+ application/json:+ schema:+ type: array+ items:+ $ref: '#/components/schemas/Client'+ application/x-www-form-urlencoded:+ schema:+ type: array+ items:+ $ref: '#/components/schemas/Client'
Underresponses
, each oldproduces
array value can have its own schema.
Response Headers
responses: '201': description: Client created headers: Location: description: URL of new client resource- type: string+ schema:+ type: string
As withparameters
,headers
no longer have atype
, but are defined by aschema
orcontent
object.
Definition Structure
parameters:- - $ref: '#/parameters/client_id'+ - $ref: '#/components/parameters/client_id'
Reusableparameters
have moved from the top-levelparameters
object to/components/parameters
.
Security Definitions
-securityDefinitions:- client_secret:- description: Session management by confidential clients.- type: oauth2- flow: password- tokenUrl: 'https://connect.authentiq.io/token'- scopes:- clients: Enable client management+ securitySchemes:+ client_secret:+ description: Session management by confidential clients.+ type: oauth2+ flows:+ password:+ tokenUrl: 'https://connect.authentiq.io/token'+ scopes:+ clients: Enable client management
Top-levelsecurityDefinitions
become the/components/securitySchemes
object. You can see that multipleflows
are now allowed per oAuth2 scheme.
Summary
And that's it for this example.
This walk-through of a conversion (by a work-in-progress converter, tracking a Release Candidate specification) does not show off any of the new features of OpenAPI 3.0.0 likelinks
andcallbacks
orcookie
parameters, but hopefully shows some of the major areas of change when converting an API definition by hand, or help you find where things have moved to if you use a converter likeswagger2openapi.
Also not shown are changes from the RC2 release candidate, including changes to thediscriminator
property. Keep your eyes peeled for an imminent release.
As ever, if you spot anything which looks incorrect by the specification, please don't hesitate to contact me. Feedback is always gratefully received.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse