In terms of allOf
syntax, both versions are correct and technically equivalent:
allOf:
- $ref: '#/components/schemas/Foo'
- properties:
# other properties
# ...
allOf:
- $ref: '#/components/schemas/Foo'
properties:
# other properties
# ...
In OpenAPI 3.1 (which uses JSON Schema 2020-12 by default), there's even no need for allOf
if you only have one $ref
because $ref
now allows sibling keywords. (But you still need allOf
to "combine" multiple $refs.)
# openapi: 3.1.0
$ref: '#/components/schemas/Foo'
properties:
# other properties
# ...
The error in your examples is elsewhere - it's the presence of additionalProperties: false
. This keyword is problematic because it only knows about its immediate sibling properties
and has no visibility into allOf/oneOf/anyOf subschemas or "inherited" schemas. For your examples, this means that properties defined in the FileInfo
schema won't actually be allowed in the composed schema.
Here are some more examples to illustrate that additionalProperties: false
doesn't work the way one would expect:
allOf:
- $ref: '#/components/schemas/Foo'
- $ref: '#/components/schemas/Bar'
additionalProperties: false
# Expected: Only the properties defined in Foo and Bar are allowed
# Actual: No properties are allowed
allOf:
- $ref: '#/components/schemas/Foo'
- properties:
prop:
type: string
additionalProperties: false
# Expected: The allowed properties are `prop` and those defined in the Foo schema
# Actual: Only the `prop` property is allowed
allOf:
- $ref: '#/components/schemas/Foo'
properties:
prop:
type: string
additionalProperties: false
# Expected: The allowed properties are `prop` and those defined in the Foo schema
# Actual: Only the `prop` property is allowed
Foo:
type: object
properties:
foo:
type: string
additionalProperties: false
Bar:
allOf:
- $ref: '#/components/schemas/Foo'
- properties:
prop:
type: string
# Expected: The Bar schema allows properties from Foo + the `prop` property
# Actual: The Bar schema allows only properties from Foo
This is solved in OpenAPI 3.1 / JSON Schema 2019-09+ by the new unevaluatedProperties: false
keyword. So the following will work the way you expect:
# openapi: 3.1.0
$ref: '#/components/schemas/Foo'
properties:
prop:
type: string
unevaluatedProperties: false