-
-
Notifications
You must be signed in to change notification settings - Fork 932
Description
API Platform version(s) affected: 2.6 (at least) and above
Description
When using JSON-LD, API Platform automatically exposes IRIs, but it also exposes some IRIs for anonymous resources which are not stable, leading to the body content changing from one answer to the other.
This is not desirable IMHO because it makes debugging and testing harder and also this results in the ETag header value being unstable which bust HTTP caches.
Before 2.7, the IRIs generation mechanism for anonymous resources relies on spl_object_id
so this could lead to the issue when the overall number or order of PHP objects changes (cache clearing or cache miss for instance).
Since 2.7, the IRI generation relies on random_bytes
so the IRI for anonymous resources becomes totally unstable preventing any HTTP caching.
Maybe I missed something but trying to override the JSON-LD context is currently of no use and the only workarounds I found are:
- override
ApiPlatform\JsonLd\ContextBuilder
and unset the@id
key manually, - or override
ApiPlatform\Symfony\Routing\SkolemIriConverter
to return a constant (empty) string.
How to reproduce
Expose an API Resource with a Doctrine embedded or a value object and hit the API using JSON-LD.
You can have a look at https://github.com/tucksaun/api-platform-iri-reproducer.
Possible Solution
IIUC the JSON-LD specs, for blank nodes the @id
key is only recommended and not mandatory (https://www.w3.org/TR/json-ld11/#identifying-blank-nodes), and is useful essentially if one wants to use node references to them which is not done automatically by API Platform for anonymous resources as far as I know
So one solution could be to allow disabling the addition of Skolem IRI to anonymous resources globally or per subresource.
I even consider that (if my assumption about @id
not being strictly required is correct) the use case where one wants to compare anonymous resources is probably an advanced use case and as such adding IRI to anonymous resources should probably be made an opt-in option?
Additional Context
Produced output (unstable):
{
"@context": "/contexts/Greeting",
"@id": "/greetings/1",
"@type": "Greeting",
"id": 1,
"name": "Tugdual",
"options": {
"@type": "Options",
"@id": "/.well-known/genid/493e0689a8264f70af65",
"notify": false
},
"foo": {
"@type": "ValueObject",
"@id": "/.well-known/genid/659262289b3472742a7a",
"bar": 42
}
}
headers (unstable):
...
etag: "753c1f46a6df1e05ae9525539d217504"
...
Desired output:
{
"@context": "/contexts/Greeting",
"@id": "/greetings/1",
"@type": "Greeting",
"id": 1,
"name": "Tugdual",
"options": {
"@type": "Options",
"notify": false
},
"foo": {
"@type": "ValueObject",
"bar": 42
}
}
headers (stable):
...
etag: "090f00d2c63731328b6a24352e4d74d8"
...