php-openapi
php-openapi copied to clipboard
Resolve: Better way to resolve allOf
Fixes https://github.com/cebe/yii2-openapi/issues/165
Also part of https://github.com/php-openapi/yii2-openapi/issues/10
@cebe
At this moment allOf wiil be only resolved for OpenAPI entities classes inheriting from SpecBaseObject.
If this pull request is approved and merged I will create similar pull request for Callbacks, Responses and Paths
Requirements:
Simple example of resolving a property:
Schema:
openapi: 3.0.3
info:
title: Resolve property
version: 1.0.0
components:
schemas:
User:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
Post:
type: object
properties:
id:
type: integer
content:
type: string
user:
$ref: '#/components/schemas/User'
paths:
'/':
get:
responses:
'200':
description: OK
After resolving the references:
components:
schemas:
User:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
Post:
type: object
properties:
id:
type: integer
content:
type: string
user:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
In the same manner allOf with reference and custom OpenAPI extension with the schema:
Post:
type: object
properties:
id:
type: integer
content:
type: string
user:
allOf:
- $ref: '#/components/schemas/User'
- x-faker: false
must be resolved as:
Post:
type: object
properties:
id:
type: integer
content:
type: string
user:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
x-faker: false
So we can access x-faker in same way as we use type, required and properties of User component schema:
/** @var \cebe\openapi\spec\Schema $user A property (similar to "content" and "id") of a Post component schema */
$user->type # 'object'
$user->required # [0 => 'id', 1 => 'name']
$user->{'x-faker'} # `false`
At this moment references are resolved but not allOf:
Array &0 (
'type' => 'object'
'properties' => Array &1 (
'id' => Array &2 (
'type' => 'integer'
)
'content' => Array &3 (
'type' => 'string'
)
'user' => Array &4 (
'allOf' => Array &5 (
0 => Array &6 (
'required' => Array &7 (
0 => 'id'
1 => 'name'
)
'type' => 'object'
'properties' => Array &8 (
'id' => Array &9 (
'type' => 'integer'
)
'name' => Array &10 (
'type' => 'string'
)
)
)
1 => Array &11 (
'x-faker' => false
)
)
)
)
)
If a duplicate property is found
components:
schemas:
User:
type: object
required:
- id
- name # <--------------------------------------------------------------
properties:
id:
type: integer
name: # <--------------------------------------------------------------
type: string
maxLength: 10 # <--------------------------------------------------------------
Pet:
type: object
required:
- id2
- name # <--------------------------------------------------------------
properties:
id2:
type: integer
name: # <--------------------------------------------------------------
type: string
maxLength: 12 # <--------------------------------------------------------------
Post:
type: object
properties:
id:
type: integer
content:
type: string
user:
allOf:
- $ref: '#/components/schemas/User'
- $ref: '#/components/schemas/Pet'
- x-faker: true
then property from the last component schema will be considered:
Post:
type: object
properties:
id:
type: integer
content:
type: string
user:
type: object
required:
- id
- name # <--------------------------------------------------------------
- id2
properties:
id:
type: integer
name: # <--------------------------------------------------------------
type: string
maxLength: 12 # <--------------------------------------------------------------
id2:
type: integer
x-faker: true
You'll have better chance in https://github.com/DEVizzent/cebe-php-openapi since this repo is abandoned.
@SOHELAHMED7 can you explain more about why you implemented the recursive resolution of allOf? allOf is a property of Schema and it only make sense to call it on a schema object. I'd expect the resolveAllOf() function inside of Schema and see it applied to sub-schemas only.
can you explain more about why you implemented the recursive resolution of allOf?
I think allOf and "reference" are very similar. "reference" can be nested so as allOf. allOf can have "reference". I have added a test case for this.. Also resolving allOf will require resolving "reference".
So I implemented resolving allOf similar to how "reference" are resolved.