This issue is based in a discussion between @klausi, @damiankloip and me.
When serializing an object that has a file field, the URI of the image is just exposed in HAL+json format but not in other formats.
For example, requesting http://d8.local/entity/node/1 with Accept: application/json returns the following info for the file entity
"field_page_file":[
{
"target_id":"1",
"display":"1",
"description":""
}
]
While if we request hal+json, we get the following (note, response is cropped):
{
"_links": {
...
"http:\/\/d8.local\/rest\/relation\/node\/page\/field_page_file": [
{
"href": "http:\/\/d8.local\/entity\/file\/1"
}
]
},
...
"_embedded": {
...
"http:\/\/d8.local\/rest\/relation\/node\/page\/field_page_file": [
{
"_links": {
"self": {
"href": "http:\/\/d8.local\/entity\/file\/1"
},
"type": {
"href": "http:\/\/d8.local\/rest\/type\/file\/file"
}
},
"uuid": [
{
"value": "73f796ef-8a15-4a0c-8e4b-75ea1caf8b12"
}
]
}
]
},
...
}
So it seems that there is a way to obtain the file URI, although the keys within _embedded and _links are not easy to grok from a programmers perspective in order to request a page node and render a file URI contained in that node.
I am about to review EntityReferenceItemNormalizer (suggested by @damiankloip) to see how other formats such as JSON include the URI of the file.
| Comment | File | Size | Author |
|---|---|---|---|
| #44 | interdiff-2124677-42.txt | 4.21 KB | damiankloip |
| #44 | 2124677-42.patch | 9.54 KB | damiankloip |
| #39 | interdiff-2124677-39.txt | 5.23 KB | damiankloip |
| #38 | interdiff-2124677-38.txt | 1.23 KB | damiankloip |
| #28 | interdiff-2124677-28.txt | 659 bytes | damiankloip |
Comments
Comment #1
juampynr commentedFirst pass. I added FileFieldItemNormalizer service. It is currently being picked up by Drupal core for File fields. Comments after uploading patch.
Comment #2
juampynr commentedSome observations from y patch:
I need to figure out how to obtain the file's URI and then add it to the $values array.
Until I am done with normalize() I won't take care of denormalisation.
Not sure if I need this.
Comment #3
juampynr commentedOK, now file fields return the URI to the file like the following when requesting a node in JSON or XML format:
And since image fields are also file entities, they are listed too. Here I added an image field to the page content type, edited the node and then requested it as JSON:
Now I will take care of what needs to be done at method denormalize().
Comment #3.0
juampynr commentedUpdated description
Comment #4
juampynr commentedThis patch adds both the URL to access the full entity (as 'uri') and the URL to access to the content directly (as 'content'), so it looks like the following:
Comment #5
juampynr commentedHere I did the following changes:
* Now using $entity->uri() in order to obtain the URI of the entity istead of building it manually.
* Added $langcode to the returned structure (as other normalizers do).
* Emptied the denormalize method since this is just needed for Normalizers that support hal+json format.
Comment #6
juampynr commentedBumping priority up to major. This makes the REST API pretty useless when a piece of content has files attached to it since their URLs are not exposed.
Comment #7
klausiwhy is that in hal module and not in the serialization module?
why do you need the language? That is already on the entity object? please add a comment.
But otherwise I think you are on the right track. We need a test case that covers this change.
Comment #8
juampynr commentedMoved to serialization module as suggested in #7. Also, removed an unneeded constructor setter and the language field since it is not needed.
Now writing the test.
Comment #9
jsbalseraComment #10
gloob commentedComment #11
mgiffordComment #12
chr.fritschComment #13
mikey_p commentedSince file fields extend entity reference, wouldn't it make sense for this to also support all entity reference items?
Comment #14
chr.fritschMaybe yes, but what about circular references? There have to be some logic to make a "cut"
Comment #15
berdirI don't see how we could have circular references here? we're just calling url(), like hal serialization is too, that could easily live on a more generic normalizer.
Also needs an issue summary update (the examples there are very old) and the issue title should clarify that this is about the json format.
Comment #17
damiankloip commentedAgree it would make sense to just support all entity reference fields with this. We can rely on ->url() as it comes from EntityInterface, along with every other method under the sun.
Comment #18
damiankloip commentedThis would make it a very similar patch to #2060677: Add target_type, target_uuid to serialized output of entity reference fields in non-HAL formats
Comment #19
damiankloip commentedFile rename not in diff due to pure laziness.
Comment #21
damiankloip commentedMaybe not assuming there will always be an entity is a good idea.
Comment #22
damiankloip commentedComment #24
damiankloip commentedThe EntitySerializationTest should have actually semi-failed already, we just weren't actually using a user in the test, so no 'url' was added from the normalizer.
Here is a modified EntitySerializationTest and a new EntityReferenceFieldItemNormalizerTest unit test.
Comment #27
dawehner+1 even using prophecy would be nicer for the tests.
Comment #28
damiankloip commentedYeah, prophecy is not a bad idea. None of the other tests use it but hey..
Comment #29
klausiComment #38
damiankloip commentedFixing a the rel param value passed to url() so config entities don't get the edit-form URL put into the normalized data.
Comment #39
damiankloip commentedConverted to prophecy, that was pretty fun!
Comment #40
dawehnerOf course it is!
Comment #41
klausican we use ::class here?
can we use ::class here?
can we use ::class here?
and here
and here
over 80 characters, can we split this up into multiple lines as we do elsewhere with chained method calls? Also elsewhere.
Comment #42
damiankloip commentedI can change that, 80 chars is not a limit on lines of code though?
Comment #43
klausiSure, but if you have 5 "->" operators on one line my head starts spinning.
Comment #44
damiankloip commentedAnd yes, you certainly can use it with interface too! :)
Comment #45
dawehnerMeh, actually I think its much more readable if input and output is in one line. At least I don't have to do that in other patches, yeah!
Comment #48
damiankloip commentedComment #51
damiankloip commentedComment #52
alexpottCommitted ba447d7 and pushed to 8.0.x. Thanks!
Comment #54
berdirThis broke file_entity tests, see #2575741: Priority of serialialization EntityReferenceFieldItemNormalizer must be lower than the one from hal
Comment #55
damiankloip commentedComment #57
wim leersThis was mocked incorrectly. See #2927566: Unit test EntityReferenceFieldItemNormalizerTest mocks incorrectly.