Closed
Description
Propose that we introduce a construct from JSON Schema draft-5, but not exactly per the draft-5 proposal.
Background
The allOf
construct requires that all members be proper JSON Schemas. For JSON-Schema draft-5,
a $merge
operator was proposed. The behavioral differences between the two include:
- merge members do not need to be valid schemas
- the
$merge
operator allows for subtraction of values - the
$merge
operator has operational order, which allows for a defined behavior when keys clash and have different values - the
$merge
operator is pre-processed, constructing a (valid) schema before validation is actually performed
The JSON schema draft has a different syntax than proposed. Why? It's too verbose, and supports a source
and with
syntax (i.e. merge two objects). We need to merge multiple objects, and the source
, with
is more wordy than we need.
Examples
Similar to allOf
, but with partial schemas:
definitions:
Dog:
$merge:
- $ref: '#/definitions/Animal'
- description: a dog
Animal:
type: object
properties:
numberOfFeet:
type: integer
format: int32
result:
definitions:
Dog:
properties:
numberOfFeet:
type: integer
format: int32
description: a dog
In addition, since we can use $merge
without full schemas, I propose a fragments
section where non-validated schemas can be used.
parameters:
- $merge:
- $ref: '#/fragments/skip'
- in: query
description: the total records to skip
minimum: null
fragments:
skip:
# this is a partial schema! It's not a proper parameter
name: skip
type: integer
format: int32
minimum: 0
The effective result:
parameters:
- in: query
description: the total records to skip
name: skip
type: integer
format: int32
# note the minimum is removed by the `null`!!!
Modeling a common pattern
components:
definitions:
PaginatedResult:
type: object
properties:
totalRecords:
type: integer
format: int32
cursorId:
type: string
UserPaginatedResult:
$merge:
- $ref: '#/components/definitions/PaginatedResult'
- properties:
data:
type: array
items:
$ref: '#/components/definitions/User'
User:
properties:
name:
type: string
Effective result:
components:
definitions:
UserPaginatedResult:
type: object
properties:
totalRecords:
type: integer
format: int32
cursorId:
type: string
# note `data` is merged, not replacing `properties`!!!
data:
type: array
items:
$ref: '#/components/definitions/User'
Metadata
Metadata
Assignees
Labels
No labels