Steps

1. Enable hal and rest modules.
2. Add a file to the page content type and create a node with a file in it.
3. Import the following REST configuration that gives access to nodes:

resources:
  'entity:node':
    GET:
      supported_formats:
        - hal_json
      supported_auth:
        - cookie

4. Open http://d8.local/node/1 with header "Accept: application/hal+json" (I normally use Dev HTTP client).

Expected

Within the HAL+JSON representation of the node we can see the file resource and the URL to the file.

Actual

File uri and href fields are empty.

Here is the full output of the node:

{
   "_links":{
      "self":{
         "href":"http:\/\/d8.local\/node\/2"
      },
      "type":{
         "href":"http:\/\/d8.local\/rest\/type\/node\/page"
      },
      "http:\/\/d8.local\/rest\/relation\/node\/page\/uid":[
         {
            "href":"http:\/\/d8.local\/user\/1",
            "lang":"en"
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/revision_uid":[
         {
            "href":"http:\/\/d8.local\/user\/0"
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/field_file":[
         {
            "href":""
         }
      ]
   },
   "uuid":[
      {
         "value":"a9d6d2bf-5d8f-4648-8c07-7b32754ce911"
      }
   ],
   "type":[
      {
         "target_id":"page"
      }
   ],
   "langcode":[
      {
         "value":"en"
      }
   ],
   "title":[
      {
         "value":"Tha title",
         "lang":"en"
      }
   ],
   "_embedded":{
      "http:\/\/d8.local\/rest\/relation\/node\/page\/uid":[
         {
            "_links":{
               "self":{
                  "href":"http:\/\/d8.local\/user\/1"
               },
               "type":{
                  "href":"http:\/\/d8.local\/rest\/type\/user\/user"
               }
            },
            "uuid":[
               {
                  "value":"37f20e01-027b-433e-a80b-111188403b70"
               }
            ],
            "lang":"en"
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/revision_uid":[
         {
            "_links":{
               "self":{
                  "href":"http:\/\/d8.local\/user\/0"
               },
               "type":{
                  "href":"http:\/\/d8.local\/rest\/type\/user\/user"
               }
            },
            "uuid":[
               {
                  "value":"1e52d459-2904-4214-8960-96d25c08e787"
               }
            ]
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/field_file":[
         {
            "_links":{
               "self":{
                  "href":""
               },
               "type":{
                  "href":"http:\/\/d8.local\/rest\/type\/file\/file"
               }
            },
            "uuid":[
               {
                  "value":"1e92c96f-f4b7-46ee-b926-38b68d186a0e"
               }
            ],
            "uri":[
               {
                  "value":"http:\/\/d8.local\/"
               }
            ]
         }
      ]
   },
   "status":[
      {
         "value":"1",
         "lang":"en"
      }
   ],
   "created":[
      {
         "value":"1401567395",
         "lang":"en"
      }
   ],
   "changed":[
      {
         "value":"1401567616",
         "lang":"en"
      }
   ],
   "promote":[
      {
         "value":"0",
         "lang":"en"
      }
   ],
   "sticky":[
      {
         "value":"0",
         "lang":"en"
      }
   ],
   "revision_timestamp":[
      {
         "value":"0"
      }
   ],
   "log":[
      {
         "value":"",
         "lang":"en"
      }
   ],
   "body":[
      {
         "value":"<p>tha body<\/p>\r\n",
         "format":"basic_html",
         "summary":""
      }
   ]
}

Comments

juampynr’s picture

Priority: Normal » Major
Status: Active » Needs review
StatusFileSize
new1.32 KB

Here is a patch that fixes the uri and href in the HAL + JSON representation. This is how it looks like with the patch:

{
   "_links":{
      "self":{
         "href":"http:\/\/d8.local\/node\/2"
      },
      "type":{
         "href":"http:\/\/d8.local\/rest\/type\/node\/page"
      },
      "http:\/\/d8.local\/rest\/relation\/node\/page\/uid":[
         {
            "href":"http:\/\/d8.local\/user\/1",
            "lang":"en"
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/revision_uid":[
         {
            "href":"http:\/\/d8.local\/user\/0"
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/field_file":[
         {
            "href":"http:\/\/d8.local\/sites\/default\/files\/README.txt"
         }
      ]
   },
   "uuid":[
      {
         "value":"a9d6d2bf-5d8f-4648-8c07-7b32754ce911"
      }
   ],
   "type":[
      {
         "target_id":"page"
      }
   ],
   "langcode":[
      {
         "value":"en"
      }
   ],
   "title":[
      {
         "value":"Tha title",
         "lang":"en"
      }
   ],
   "_embedded":{
      "http:\/\/d8.local\/rest\/relation\/node\/page\/uid":[
         {
            "_links":{
               "self":{
                  "href":"http:\/\/d8.local\/user\/1"
               },
               "type":{
                  "href":"http:\/\/d8.local\/rest\/type\/user\/user"
               }
            },
            "uuid":[
               {
                  "value":"37f20e01-027b-433e-a80b-111188403b70"
               }
            ],
            "lang":"en"
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/revision_uid":[
         {
            "_links":{
               "self":{
                  "href":"http:\/\/d8.local\/user\/0"
               },
               "type":{
                  "href":"http:\/\/d8.local\/rest\/type\/user\/user"
               }
            },
            "uuid":[
               {
                  "value":"1e52d459-2904-4214-8960-96d25c08e787"
               }
            ]
         }
      ],
      "http:\/\/d8.local\/rest\/relation\/node\/page\/field_file":[
         {
            "_links":{
               "self":{
                  "href":"http:\/\/d8.local\/sites\/default\/files\/README.txt"
               },
               "type":{
                  "href":"http:\/\/d8.local\/rest\/type\/file\/file"
               }
            },
            "uuid":[
               {
                  "value":"1e92c96f-f4b7-46ee-b926-38b68d186a0e"
               }
            ],
            "uri":[
               {
                  "value":"http:\/\/d8.local\/sites\/default\/files\/README.txt"
               }
            ]
         }
      ]
   },
   "status":[
      {
         "value":"1",
         "lang":"en"
      }
   ],
   "created":[
      {
         "value":"1401567395",
         "lang":"en"
      }
   ],
   "changed":[
      {
         "value":"1401567616",
         "lang":"en"
      }
   ],
   "promote":[
      {
         "value":"0",
         "lang":"en"
      }
   ],
   "sticky":[
      {
         "value":"0",
         "lang":"en"
      }
   ],
   "revision_timestamp":[
      {
         "value":"0"
      }
   ],
   "log":[
      {
         "value":"",
         "lang":"en"
      }
   ],
   "body":[
      {
         "value":"<p>tha body<\/p>\r\n",
         "format":"basic_html",
         "summary":""
      }
   ]
}
mashermike’s picture

I was able to reproduce the issue and the patch adds the specified values:

href and uri output urls which point to the the file.

mashermike’s picture

Status: Needs review » Reviewed & tested by the community

I read through the patch and the fix is clean and simple.

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Looks like there's test coverage missing.

mashermike’s picture

Status: Needs work » Needs review
StatusFileSize
new3.29 KB
new4.54 KB

Here is a test only patch which should fail and a patch with fixes included.

I reworked the normalization fix to be more in line with how the rest of the module handled it.

The last submitted patch, 5: drupal-file-uri-href-empty-2277705.test_only.patch, failed testing.

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

Looks sane to me.

xjm’s picture

+++ b/core/modules/file/src/Entity/File.php
@@ -77,6 +77,13 @@ public function setFileUri($uri) {
+  public function url($rel = 'canonical', $options = array()) {
+    return file_create_url($this->getFileUri());

So we're calling out to a procedural file.module function here from a class. It's not a big deal since both belong to the File module and shouldn't block this, but possibly something to clean up in a followup?

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 8.x. Thank you.

  • Commit 505a062 on 8.x by Dries:
    Issue #2277705 by mashermike, juampy: Fixed Files don't have URI nor...
xjm’s picture

Issue tags: -Needs tests

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

arla’s picture

Status: Closed (fixed) » Postponed

When #1927648: Allow creation of file entities from binary data via REST requests goes through, this issue should probably be revisited. The 'uri' base field should then definitely be kept unmodified by normalization, and the URI for the href should instead be set by overriding getEntityUri() in FileEntityNormalizer.

juampynr’s picture

Status: Postponed » Closed (fixed)

@Arla, I am closing this issue again as we do not reopen closed ones. Please create a follow up issue instead that references the other two.

wim leers’s picture

This patch solved a symptom rather than the root cause.

In doing so, it introduced a lot of technical debt, which cannot be removed until Drupal 9: we must retain BC. Read about the consequences in #2825487-128: Fix normalization of File entities: file entities should expose the file URL as a computed property on the 'uri' base field.17.

Also: this is categorized against the wrong component…

Posting this comment for future readers. And especially to add the related issue.

wim leers’s picture

wim leers’s picture

It'd be great if the people who worked on this would help with sorting out the way forward in #2922487: Follow-up for #2910211: fix all deprecation warnings.