Skip to content

Support prefixItems for OpenAPI 3.1 schemas (parse + positional tuple validation + PrefixItemsIn30 rule) - #202

Open
takayamaki wants to merge 4 commits into
ota42y:masterfrom
takayamaki:pr13-prefixitems
Open

Support prefixItems for OpenAPI 3.1 schemas (parse + positional tuple validation + PrefixItemsIn30 rule)#202
takayamaki wants to merge 4 commits into
ota42y:masterfrom
takayamaki:pr13-prefixitems

Conversation

@takayamaki

Copy link
Copy Markdown
Contributor

Continuing the OpenAPI 3.1 work from #152.

OpenAPI 3.1 adopts the JSON Schema 2020-12 prefixItems keyword,
which validates the leading elements of an array positionally (tuple typing).
3.0 has no equivalent — it only has items, which applies uniformly to every element.

This PR adds parse support, runtime validation, and version-mismatch detection.

Parse layer

prefixItems is parsed as a list of Schema objects and exposed as an accessor:

schema.prefix_items # => [#<Schema type="string">, #<Schema type="integer">]

The Ruby accessor is snake_case with schema_key: :prefixItems,
matching how all_of / any_of / additional_properties are already declared.
Following the permissive-parse strategy agreed in #152,
the parse layer accepts prefixItems regardless of the declared OpenAPI version.

Runtime validation

ArrayValidator dispatches per position:
element i is validated against prefixItems[i] when one exists,
and falls back to items otherwise.
This is how JSON Schema 2020-12 layers the two keywords.

# schema: { type: array, prefixItems: [{type: string}, {type: integer}], items: {type: boolean} }
validate(['a', 1])              # => ok
validate(['a', 'x'])            # => ValidateError (position 1 must be an integer)
validate(['a', 1, true, false]) # => ok (extras fall through to items)
validate(['a', 1, 'x'])         # => ValidateError (extras must be booleans)

A schema with prefixItems but no items leaves the trailing elements unvalidated,
which matches JSON Schema's default of an absent items being unconstrained.

SpecValidator rule

PrefixItemsIn30 reports a violation for each schema in a 3.0 document that uses prefixItems:

OpenAPIParser.load(
  'spec.yaml',
  strict_specification_version: :warn,
)
# [PrefixItemsIn30] #/components/schemas/Tuple — `prefixItems` is a 3.1 addition (from JSON Schema 2020-12); 3.0 has no equivalent

…y PR13)

- Schema gains a `prefixItems` list-of-Schema accessor
- Rules::PrefixItemsIn30 flags the keyword on 3.0 documents
- ArrayValidator now positional-dispatches: leading elements match the
  prefixItems schemas, the rest fall back to schema.items
`prefixItems` on a 3.0 document warns and raises (JSON Schema 2020-12
tuple keyword with no 3.0 equivalent); the same keyword on a 3.1
document stays clean.
@takayamaki
takayamaki marked this pull request as ready for review August 19, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant