-
-
Notifications
You must be signed in to change notification settings - Fork 853
fix(ModelRegistry): schemas deduplication now compare generated schemas to reduce automatically named schemas #2461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 5.x
Are you sure you want to change the base?
Conversation
I missed the release of the version 5.0, congrats to everyone involved 🎉 ! |
ebbb047
to
eec12f7
Compare
I decided to target 5.x as tests were failing for SF 5.4 ^^ |
eec12f7
to
83b716a
Compare
Either is fine really 😄 |
Ok I'll stick with 5.x so ^^ Thanks ! |
83b716a
to
8fcd95e
Compare
@DjordyKoert branch rebased on 5.x. Do you have any thoughts to share on this pull request ? Thks ! |
self::assertEquals('#/components/schemas/User', $response->content['application/json']->schema->ref); | ||
self::assertEquals('#/components/schemas/User2', $response->content['application/json']->schema->ref); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is correct, is it?
The order of the generated schema's has been swapped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it's been swapped because now when you register a Model, the whole model is described and names are reserved for all dependencies. So in this example when the first route in ApiController is parsed (fetchArticleAction
), the model new Model(type: Article::class, groups: ['light'])
is registered and the name User
is reserved for the empty User
model (because User
has no property with the serialization group light
).
When it comes to /swagger/implicit
, the name User
has already been taken, so the full entity User
with all properties (because no serialization group has been applied) is described as User2
.
It may be pretty hard to avoid that, however I think that this behavior is more predictable. WDYT ?
src/Model/ModelRegistry.php
Outdated
@@ -97,6 +125,23 @@ public function register(Model $model): string | |||
return OA\Components::SCHEMA_REF.$this->names[$hash]; | |||
} | |||
|
|||
private function getSchemaWithoutRegistration(Model $model): ?OA\Schema |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we re-use this new method in the registerSchemas
method aswell?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I renamed this method describeSchema
and used it in registerSchemas
and register
$this->unregistered = array_unique($this->unregistered); | ||
// Only store schema if it was successfully generated | ||
if (null !== $schema) { | ||
$this->schemasPerType[$type][] = ['schema' => json_encode($schema), 'model' => $model]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not store the Schema object directly instead of json encoding it?
$this->schemasPerType[$type][] = ['schema' => json_encode($schema), 'model' => $model]; | |
$this->schemasPerType[$type][] = ['schema' => $schema, 'model' => $model]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do that yes, but we have to use json_encode for comparison. Because:
- We cannot use strict equality here as instances are different
- We cannot use lose equality either, because of a cyclic dependency we go into an infinite loop
So if we decide to store the schema and not it's json representation, we would have to run json_encode and there is a lot of ops in OpenApi\Annotations\AbstractAnnotation::jsonSerialize
, so I assumed it would be better to json_encode only once.
WDYT ?
dbc4508
to
8c44c1f
Compare
…ically named schemas (Entity / Entity2 / Entity3 / ...).
8c44c1f
to
830fd2b
Compare
Description
This pull requests implements a better deduplication of schemas. It now compares the generated schemas, so even with different hashes (because of 2 different serializationContexts), we can have only 1 component if the output is identical.
The common use case for me is the following:
You can notice that
SecondLevelEntity
is always included in the response, because of the group "default".The current output is something like this:
Descriptions for
SecondLevelEntity
andSecondLevelEntity2
are the same (makes sense). With that pull request we get rid ofSecondLevelEntity2
and the reference inFirstLevelEntity2
will beSecondLevelEntity
.You may notice a few changes in other tests, the current change alters the order of the Schemas, so the generated names may vary (like
User
becomingUser2
and vice-versa).What type of PR is this? (check all applicable)
Checklist
docs/
)CHANGELOG.md
)