Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I'm not sure how/why this started happening, but when I turn on rest.module and hit http://8x.localhost:8082/entity/node/1 in my browser, I get:
<response>
<nid>
<value>1</value>
</nid>
<uuid>
<value>1d0b7f7c-18e6-4023-a700-bef36f2e00c3</value>
</uuid>
<vid>
<value>1</value>
</vid>
<type>
<value>article</value>
</type>
...
Awesome! Didn't even need to carefully craft some cURL request to send an Accept header!
However, if I hit a REST export view in my browser, I get:
Error
The website has encountered an error. Please try again later.
Error message
Symfony\Component\Serializer\Exception\UnexpectedValueException: Serialization for the format html is not supported in Symfony\Component\Serializer\Serializer->serialize() (line 78 of /Users/webchick/Sites/8.x/core/vendor/symfony/serializer/Symfony/Component/Serializer/Serializer.php).
This is decidedly un-user friendly. :)
Let's figure out how rest.module is doing its magic for entities and get it to do it for Views as well. :)
Comment | File | Size | Author |
---|---|---|---|
#32 | drupal-1969870-32.patch | 2.75 KB | dawehner |
#32 | interdiff.txt | 902 bytes | dawehner |
#26 | drupal-1969870-26.patch | 2.75 KB | dawehner |
#26 | interdiff.txt | 810 bytes | dawehner |
#25 | drupal-1969870-25.patch | 2.78 KB | dawehner |
Comments
Comment #1
dawehnerThat's just a simple fix, read for more information below and how to fix it on the longrun.
The way the rest modules handles it is the following:
It registers one route per format, so for example entity/node/{node} for json, xml. As there is no special content-type requested, the acceptable mime-types are:
(@see MimeTypeMatcher::filter()
so basically all routes match. As far as I understand the routing system, the one who comes first then wins, which is (maybe not on purpose) xml.
Views could get such a default behavior when it would use the route system. Though there is currently a dependency tree:
Comment #3
dawehner#1: drupal-1969870-1.patch queued for re-testing.
Comment #4
linclark CreditAttribution: linclark commentedYou're right about XML not being on purpose. I think that we should probably make it default to JSON in both places, XML is serialization module's red headed stepchild.
Comment #5
webchickOk, sounds then like this is postponed on those other issues for now, since we don't want to hard-code in red-headedness.
Comment #6
damiankloip CreditAttribution: damiankloip commentedLet's leave it postponed, but I agree with lin - JSON should be the default format served.
Comment #7
dawehnerI don't know but I think we should get this in first, because a) the other issues still need time (*hint* #1956896: Add role based access checker is RTBC)
and also this patch adds some kind of test, which is always helpful. Beside from this, it wouldn't block the other issue, as I guess we should not fix the needed behavior of this issue in #1800998: Use route system instead of hook_menu() in Views
Comment #8
damiankloip CreditAttribution: damiankloip commentedOk, let's just try and get this in then - Should be pretty simple.
I think this approach would be better; To set the contentType property on RestExport to 'json', and only override it if it's not html. Thoughts?
Comment #9
dawehnerI'm wondering whether it should be json or hal_json by default.
Comment #10
webchickWell, it's tricky, right? Because it should be whatever the primary serialization format is. Currently, D8 ships with both json-ld and hal+jason, but both are optional modules, separate from REST.
Comment #11
dawehnerShould then logic then be:
If hal_json is enabled use hal_json
If json_ld is enabled use json_ld
else use json?
Comment #12
moshe weitzman CreditAttribution: moshe weitzman commentedyes, that logic makes sense but even simpler since jsonld is poised for removal. #1935548: Remove JSON-LD module
Comment #13
dawehnerAdded this logic without taking care about json_ld.
Comment #15
damiankloip CreditAttribution: damiankloip commentedJust fixing it up. I'm not really a fan of having conditional module logic in the display plugin like this. Especially as hal will only work with entities aswell?
Comment #16
dawehnerGreat, Thank you. The code looks fine, so it's just about a comment of lin.
Comment #17
linclark CreditAttribution: linclark commentedDamian is right, HAL will only work with entities.
I think we can simply default to JSON in this case. The only thing that HAL buys you over JSON is that it has link relations... and link relations are only important to you if you are a machine. Since this is about what gets shown in the browser, we're probably working with a human user, so the hypermedia special sauce isn't necessary.
Comment #18
damiankloip CreditAttribution: damiankloip commentedThanks Lin. I was always of the mindset that JSON should be our default format, you explain things really well though :) Defaulting to hal just doesn't make sense.
This is a mix of previous patches (logic from #8 and test from #13), reverting hal_json back to json.
Comment #19
dawehnerIt's good to see that the logic is quite simple
Comment #20
alexpottShouldn't this be
$this->setContentType($this->contentType);
Comment #21
alexpottOr maybe the comment is just confusing...
Comment #22
dawehnerI don't think it's needed to set it to json if it's already set onto json?
Maybe this small change helps to understand the comment?
Comment #23
alexpottthanks @dawehner that comment is indeed clearer.
I don't think the hal module has anything to do with this.
Comment #24
alexpottEDIT: duplicate comment
Comment #25
dawehnerGood catch.
Comment #26
dawehnerAs always alex spotted that there is no json module, let's get rid of the module comment.
Comment #27
damiankloip CreditAttribution: damiankloip commentedLooks good to me. Alex?
Comment #28
alexpott+1
Comment #29
damiankloip CreditAttribution: damiankloip commentedIf Alex is happy with the new comment I think we're good to go again.
Comment #30
damiankloip CreditAttribution: damiankloip commentedOh
Comment #31
alexpottOk I've now understood why this patch confuses me...
To me this should be...
Comment #32
dawehnerComment #33
tim.plunkettSimple enough.
Comment #34
effulgentsia CreditAttribution: effulgentsia commentedDoesn't this violate HTTP spec? If the agent asked for html, why should we return json?
Comment #35
alexpottCommitted fc886f5 and pushed to 8.x. Thanks!
Comment #36
xjm#34 to #35 was a crosspost; do we want to reopen the discussion?
Comment #37
effulgentsia CreditAttribution: effulgentsia commentedRe #34, I don't object that this was committed, given that in practice, browsers include */* in their Accept header, but we don't yet have #1505080: [META] Content Negotiation for Accept Headers in place in order to handle that correctly. Perhaps after that issue though, we can revisit the implementation of what was committed here in order to not return json for a hypothetical agent that requested html (and nothing but html).
Comment #38
effulgentsia CreditAttribution: effulgentsia commentedSince this issue is marked fixed and will therefore, fall off our radar, I also left a comment in #1505080-40: [META] Content Negotiation for Accept Headers and raised the priority of that issue.
Comment #39
damiankloip CreditAttribution: damiankloip commented@effulgentsia: so even if/when we do have this content negotiation, what do you propose to server when html is requested? serializer doesn't support html, or do you want to add an encoder for that? Throwing an error etc.. didn't fly with people before, so not sure.
Comment #40
effulgentsia CreditAttribution: effulgentsia commentedOnce both content negotiation and #1800998: Use route system instead of hook_menu() in Views are in, then when dynamically creating the route for a View that has only a REST export display, we'll need to do a
$route->setRequirement('_format', $supported_serialization_formats);
. If an agent asks for the URL without anything in the Accept header that matches a supported format, then the routing system will return a HTTP 415 (Unsupported Media Type) status code.That's because most browsers include
*/*
in their Accept header, so they're capable of displaying JSON, and it's convenient for debugging to take advantage of that. But for agents that specifically ask for 'text/html' only, we need to honor that by returning a 415.Comment #42
Wim LeersWe're dealing with the fallout/consequences of this over at #2449143: REST views specify HTML as a possible request format, so if there is a "regular" HTML view on the same path, it will serve JSON: this breaks as soon as you have a non-REST view and a REST view on the same path: then the routing system will pick the REST view over the non-REST view, resulting in JSON/XML/… instead of HTML.
Comment #43
Wim LeersThis patch only touched the REST module.