Problem/Motivation
In #1927648: Allow creation of file entities from binary data via REST requests we need to be able to provide a different set of request formats to the accepted content type formats. I.e. we only allow a bin format for file uploads as the content type format (= request format), but we need to allow a different format like json to be returned as the response (= response format). You could currently specify the correct (different) _format and _content_type_format requirement on your routes, but ResourceResponseSubscriber doesn't allow request formats to take precedence.
Proposed resolution
Try and return an acceptable request format first in \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::getResponseFormat, rather than just acceptable formats (which is derived based on whether the HTTP method is cacheable or not).
Remaining tasks
User interface changes
N/A
API changes
Addition that REST routes can specify different request and content type formats and those actually getting used.
Data model changes
N/A
| Comment | File | Size | Author |
|---|---|---|---|
| #17 | 2901704-17.patch | 14.81 KB | wim leers |
| #2 | 2901704-PASS.patch | 8.38 KB | damiankloip |
| #2 | 2901704-tests-only-FAIL.patch | 7.48 KB | damiankloip |
Comments
Comment #2
damiankloip commentedComment #4
damiankloip commentedThis is the only change for this to work.
I think we might want to add a couple more cases that use the new parameter for the data provider and helper method that creates route requirements. Maybe at least one that switches JSON and XML at least.
Comment #5
damiankloip commentedThinking about it more, I'm not sure there is much point in an inverse case to the one provided by this patch. We don't need to test every format permutation, and don't in this test class anyway?
Comment #6
wim leersComment #7
wim leersYou're saying you'd also like to test the inverse of this, right? Sounds good.
Comment #8
wim leersSo the second parameter here (
['xml']) and the last one (['json']) are the ones that are relevant here. It'd be more logical if they'd be passed after each other. But you chose not to do that to minimize changes most likely.That new parameter that you added to the end is the that's optional for the new
generateRouteRequirements()method.I think it'd be better to always require a
$supported_request_formatsand$supported_response_formatsparameter. IfNULLwould be passed to either one, then either_format(for$supported_response_formats) would not be set, or_content_type_format(for$supported_request_formats) would not be set.I think that'd make things much clearer, because explicit.
Comment #9
wim leersThis is confusing, because
$acceptable_request_formatsis a misnomer (my bad!).i.e. this code has confusing variable names (which I introduced, so totally my fault!):
I think
would be 100x clearer.
Comment #10
wim leersFixing all that.
Comment #11
wim leersFirst fixing #9. This is effectively fixing the confusing bits I introduced in #2807501: ResourceResponse::$responseData is serialized, but is never used: unserializing it on every Page Cache hit is a huge performance penalty. It's in-scope to clean it up here, since we're touching these very lines, and the confusing names (and comments) are making the solution more confusing than it is!
Comment #12
wim leersImplemented #8.
Comment #13
wim leersAnd finally, implemented #7. And also fixed some strings that were incorrect and therefore misleading.
I'm hereby RTBC'ing the changes in #2. Which means @damiankloip can now RTBC the changes I made on top of his.
Comment #14
wim leersComment #15
damiankloip commentedAll of these changes look great to me! Yes, I just added it as a final optional parameter to minimise changes, but this was not really necessary as this is a test class. Just..
mega-nit: double space.
This could just be fixed on commit... Marking as RTBC.
Comment #16
larowlanThis looks good - couple of minor observations.
Also I think it would be good to get someone who maintains routing system to sign off on this too - e.g. dawehner
looks like something was missed here?
Otherwise including and particularly when the clientseems like something skipped?nit: should we have third argument TRUE here?
The previous if returned, and this hunk returns too. While we're here should we make this just a normal
ifinstead of anelseiffor easier readability? - also, should use third argument to in_arrayComment #17
wim leersbit though because it returns directly. I personally think the current code more legible. But I don't feel strongly. Changed per your request. Note that this made the patch more invasive!
Comment #18
dawehnerAm I? I thought I wasn't
I love this improvement!
I'd have argued that we should ensure that the patch doesn't change stuff unrelated with this issue. To be fair though by renaming variables we already opened up the can of worms...
Comment #19
larowlanI wrote a draft change notice for this - please review https://www.drupal.org/node/2910338
Comment #20
wim leersRefined change notice.
Comment #22
larowlanCommitted as 647b586 and pushed to 8.5.x
Published change record
Comment #23
wim leersYay, one less blocker for #1927648: Allow creation of file entities from binary data via REST requests!