OpenAPI using an "extended subset" of JSON Schema has caused confusion in the API space since before I had even heard of OpenAPI. Thanks to a lot of hard work from a lot of people over the last 6 months, OpenAPI v3.1 will in fact solve this problem, and there was much rejoicing.
For anyone who's not read a million words on the topic from me on this topic already, I was talking about the divergence in 2017. It feels like forever ago now that I was just Googling around trying to figure out which API description format to recommend at WeWork. Somehow I got sucked right into this world, as I have sent pull requests to OpenAPI, got on the core team of JSON Schema, and work for Stoplight building tooling for them both. 🤣
In some places some have also said that converging the with JSON Schema would make sense for
typespecifically, so I'm seeing very mixed signals about JSON Schema 100% compliance. We'll have to see what happens in 3.1.
Well past-Phil, you got it, OpenAPI v3.1 will indeed solve the divergence between JSON Schema and the OpenAPI Schema Object. Thank f**k.
Here's the wording from the new OpenAPI specification:
The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is a superset of the JSON Schema Draft 2019-09 specification.
Unless stated otherwise, the property definitions follow the JSON Schema.
Booyeah. It uses the the Core and Validation vocabularies, and there is no list of which keywords it supports, because it's all of them. If a keyword exists in JSON Schema Draft 2019-09 (Core or Validation), then it's good to use in OpenAPI v3.1.
type can now be an array
Type works the same for OpenAPI and JSON Schema, which was always tripping people over the most.
type: string nullable: true
type: [string, "null"]
This actually used to work in some tooling for OpenAPI v3.0. Stoplight Docs, ReDoc, and others, would all support either because so many people used to use it, then the second they tried to use different tooling it would explode.
type has always been optional
OpenAPI v3.1 (and v3.0.3 for that matter) added some clarifications that if type is not there, it should have always meant
any. Some tooling would just explode, completely unable to handle a world where something doesn't have a type.
enum: - "foo" - 123 - false
This should be evaluated as though it is literally:
type: [string, number, boolean, "null", array, object] enum: - "foo" - 123 - false
Nullable needed a little clarification to make this clear.
format from JSON Schema is fine
JSON Schema Draft 2019-09 added a few new formats so go wild with those. There are some changes to how formats are interpreted now, and they are being relaxed from validation, to annotations which could be used for validation if configured to do so.
Basically, trying to validate that data follows the rules for what a specific validation tool things is valid for that format is... awful. Different tools disagree about what an email address is, despite there being a standard for what a valid email address is.
Every now and then somebody would add arbitrary keywords to their JSON Schema files, and their JSON Schema-based tooling would be fine with it, then they'd try and use those in OpenAPI only to find it blows up. We fixed this too.
In addition to the JSON Schema properties defined in the vocabularies defined in the JSON Schema Core and JSON Schema Validation specifications, any properties can be used from any vocabularies, or entirely arbitrary keywords.
OpenAPI v3.0 would only allow "extensions", which were arbitrary keywords starting with
x-. Now, no need for the
x-, unless you like it, in which case carry on. 👍
example vs examples
This has been the cause of much confusion for a long time.
JSON Schema has
examples which is a bare array, which means you can have a string with two possible examples like this:
type: string examples: - squirtle - charmander
Documentation tools could chose to show the first one, or both, doesn't matter they're both good choices.
OpenAPI v3.0 was a little different:
type: string example: squirtle
JSON Schema based tooling would not know what
example was, and OpenAPI tooling would choke when it saw
examples because it is not a valid keyword inside the Schema Object.
In OpenAPI v3.1 the Schema Object
example keyword is deprecated, so you should start using
examples in your API description documents.
I will probably add a Spectral rule for that to help nudge people in the right direction.
examples are not examples
The change above does solve a discrepancy, but it does unfortunately introduce its own little bit of confusion. Hold onto your butts.
In OpenAPI v3.0 you could only have the one example, unless... you use the not-in-the-schema approach to examples which OpenAPI offers:
parameters: - in: query name: limit schema: type: integer maximum: 50 examples: # Multiple examples zero: # Distinct name value: 0 # Example value summary: A sample limit value # Optional description max: # Distinct name value: 50 # Example value summary: A sample limit value # Optional description
Example from Swagger.io talking about Examples.
responses, outside of the Schema Object, there is a special OpenAPI keyword called
examples. This is not a bare array like the JSON Schema
examples, but an object where the keys are names, and the example has to go inside the
This confusion of two types of
examples is going to persist, but at least this problem can be solved with documentation and tutorials, instead of being a roadblock making files be unusable in some tooling but fine in others. 😅
More to Come
The work for JSON Schema alignment is pretty much done, but there are a few licks of paint until its completely sorted. These tweaks might come in over the course of the release candidate process, the first of which is supposedly going to be the end of February (this month?! 🤯)
OpenAPI v3.1 has a bunch of other cool stuff coming too:
- webhooks which do not have to be documented as callbacks underneath a specific operation
pathsis optional so an API description could be webhooks only
- maybe overlays will be a thing
We'll talk about all this in future articles in the future. Until then, make sure your tooling is ready for JSON Schema 2019-09 and OpenAPI v3.1.
Many tooling vendors are hard at work on this as we speak, and if you'd like an already-done reference project to help, check out Manatee.Json.