-
-
Notifications
You must be signed in to change notification settings - Fork 900
fix(jsonschema): generation of non-LD+JSON distinct schema formats #6236
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
Conversation
73f70fc
to
c555d4e
Compare
3d6ba7c
to
97f7dff
Compare
97f7dff
to
9ddeb26
Compare
src/Symfony/Bundle/DependencyInjection/Compiler/SchemaFactoryPass.php
Outdated
Show resolved
Hide resolved
774bb65
to
25a9d4f
Compare
'items' => $items, | ||
], | ||
], | ||
], |
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.
something's bothering me here I need to check that, I don't understand why we put array
in the first place.
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.
Introduced in #4357, as was addDistinctFormat()
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.
https://datatracker.ietf.org/doc/html/draft-kelly-json-hal#section-4.1.2
It is an object whose property names are link relation types (as defined by [RFC5988]) and values are either a Resource Object or an array of Resource Objects.
can you revert this change? I think that our HAL representation always uses an array and we use items
as key.
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.
Doesn't that make the behaviour in ApiPlatform\Hal\Serializer\CollectionNormalizer
incorrect?
core/src/Hal/Serializer/CollectionNormalizer.php
Lines 86 to 100 in 874e4d6
protected function getItemsData(iterable $object, ?string $format = null, array $context = []): array | |
{ | |
$data = []; | |
foreach ($object as $obj) { | |
$item = $this->normalizer->normalize($obj, $format, $context); | |
if (!\is_array($item)) { | |
throw new UnexpectedValueException('Expected item to be an array'); | |
} | |
$data['_embedded']['item'][] = $item; | |
$data['_links']['item'][] = $item['_links']['self'] ?? null; | |
} | |
return $data; | |
} |
The changes in ApiTestCaseTest
(testing jsonld
and jsonhal
as formats) trigger a failure condition without this change:
1) ApiPlatform\Tests\Symfony\Bundle\Test\ApiTestCaseTest::testAssertMatchesResourceCollectionJsonSchema with data set "jsonhal" ('jsonhal', 'application/hal+json')
Failed asserting that Array &0 (
'_links' => Array &1 (
'self' => Array &2 (
'href' => '/resource_interfaces'
)
'item' => Array &3 (
0 => Array &4 (
'href' => '/resource_interfaces/item1'
)
1 => Array &5 (
'href' => '/resource_interfaces/item2'
)
)
)
'_embedded' => Array &6 (
'item' => Array &7 (
0 => Array &8 (
'_links' => Array &9 (
'self' => Array &10 (
'href' => '/resource_interfaces/item1'
)
)
'foo' => 'item1'
'fooz' => 'fooz'
)
1 => Array &11 (
'_links' => Array &12 (
'self' => Array &13 (
'href' => '/resource_interfaces/item2'
)
)
'foo' => 'item2'
'fooz' => 'fooz'
)
)
)
) matches the provided JSON Schema.
_embedded: Object value found, but an array is required
2) ApiPlatform\Tests\Symfony\Bundle\Test\ApiTestCaseTest::testAssertMatchesResourceCollectionJsonSchemaKeepSerializationContext with data set "jsonhal" ('jsonhal', 'application/hal+json')
Failed asserting that Array &0 (
'_links' => Array &1 (
'self' => Array &2 (
'href' => '/issue-6146-parents'
)
'item' => Array &3 (
0 => Array &4 (
'href' => '/issue-6146-parents/1'
)
)
)
'totalItems' => 1
'itemsPerPage' => 3
'_embedded' => Array &5 (
'item' => Array &6 (
0 => Array &7 (
'_links' => Array &8 (
'self' => Array &9 (
'href' => '/issue-6146-parents/1'
)
)
)
)
)
) matches the provided JSON Schema.
_embedded: Object value found, but an array is required
3) ApiPlatform\Tests\Symfony\Bundle\Test\ApiTestCaseTest::testAssertMatchesResourceItemAndCollectionJsonSchemaOutputWithContext with data set "jsonhal" ('jsonhal', 'application/hal+json')
Failed asserting that Array &0 (
'_links' => Array &1 (
'self' => Array &2 (
'href' => '/users-with-groups'
)
'item' => Array &3 (
0 => Array &4 (
'href' => '/users/1'
)
)
)
'totalItems' => 1
'itemsPerPage' => 3
'_embedded' => Array &5 (
'item' => Array &6 (
0 => Array &7 (
'_links' => Array &8 (
'self' => Array &9 (
'href' => '/users/1'
)
)
'fullname' => 'Grégoire'
)
)
)
) matches the provided JSON Schema.
_embedded: Object value found, but an array is required
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.
From https://datatracker.ietf.org/doc/html/draft-kelly-json-hal#section-6
{
"_links": {
"self": { "href": "/orders" },
"next": { "href": "/orders?page=2" },
"find": { "href": "/orders{?id}", "templated": true }
},
"_embedded": {
"orders": [{
"_links": {
"self": { "href": "/orders/123" },
"basket": { "href": "/baskets/98712" },
"customer": { "href": "/customers/7809" }
},
"total": 30.00,
"currency": "USD",
"status": "shipped",
},{
"_links": {
"self": { "href": "/orders/124" },
"basket": { "href": "/baskets/97213" },
"customer": { "href": "/customers/12369" }
},
"total": 20.00,
"currency": "USD",
"status": "processing"
}]
},
"currentlyProcessing": 14,
"shippedToday": 20
}
Which also comes back to a previous question as to the key(s) of _embedded
… internally items
is used but the examples in the draft seem to use the resource name.
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.
To be correct the schema should be anyOf
object or array. We force item
at
$data['_embedded']['item'][] = $item; |
item
as I see it.
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.
As in how I did it originally in 97f7dff?
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.
Ugh, never mind, it clicked what you meant … now (I think) I get you 😇
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.
Looking too hard at the same thing for too long and got my brain in a twist.
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.
Right now we may have (as this is what we use for our collections and):
'anyOf' => [
[
// see features/hal/collection.feature
'type' => 'object',
'properties' => [
'item' => [
'type' => 'array',
'items' => $items,
],
],
],
// see features/hal/hal.feature
[ 'type' => 'object' ]
],
Although the spec says that it can also be
// according to what I understand from the spec this is also valid:
[
'type' => 'array'
],
I'm okay with adding it if you want
src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
Outdated
Show resolved
Hide resolved
cf0f4b1
to
4f93952
Compare
@soyuka I have also updated more of the tests in If you want to suggest other test locations that I can expand on, I'll happily work away on them. |
src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
Outdated
Show resolved
Hide resolved
b4df084
to
e3f0e4f
Compare
took the liberty of adding the correct schema in a new commit I want to check that the CI is green |
Thanks @GwendolenLynch ! Feel free to propose the |
I've not figured out a good way to CI test this, so guidance will be gratefully appreciated.
To reproduce the base issue, apply the following to the
3.2
branch and runvendor/bin/simple-phpunit --filter JsonSchemaGenerateCommandTest::testSubSchemaJsonLd