Problem/Motivation
See #2829977: SerializableHttpException and Drupal\jsonapi\Error\* are not necessary, specifically #2829977-25: SerializableHttpException and Drupal\jsonapi\Error\* are not necessary. The most relevant info of that issue:
We had the same problem in the REST module, and we fixed that in #2807501: ResourceResponse::$responseData is serialized, but is never used: unserializing it on every Page Cache hit is a huge performance penalty. We want the exact same solution here. Then there is no need for a
__sleep()
method. Yes, that means we're duplicating code from the REST module. But better a duplication than an incorrect abstraction. If it turns out that it's the right abstraction, we can move the code for this over to the Serialization module. So that still leaves open the door for future simplification. For now, what matters is that we follow the exact same pattern.In other words: we should revert the changes made by #2818221: [BUGFIX] Restore serialization with HttpException inline responses and instead introducing the same solution that is used in core's
rest
module: #2807501: ResourceResponse::$responseData is serialized, but is never used: unserializing it on every Page Cache hit is a huge performance penalty. Opened #2855693: Remove \Drupal\jsonapi\Controller\RequestHandler::renderJsonApiResponse(), add \Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber for that, because tacking that onto this issue will make this issue/patch very very difficult to review.
Postponed on #2829977: SerializableHttpException and Drupal\jsonapi\Error\* are not necessary, which is postponed on #2841027: JSON API format should only be used on JSON API routes, but can currently also be used for REST resources.
Proposed resolution
- Remove \Drupal\jsonapi\Controller\RequestHandler::renderJsonApiResponse()
- Add
ResourceResponseSubscriber
- Add explicit test coverage proving it works correctly with Dynamic Page Cache
Remaining tasks
None.
User interface changes
None.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#21 | 2855693-21.patch | 21.7 KB | Wim Leers |
|
Comments
Comment #2
Wim LeersComment #3
Wim Leers\Drupal\Tests\jsonapi\Kernel\Controller\RequestHandlerTest
's only purpose is testing the automatic validation of JSON API responses against JSON API's JSON schema. That code now lives in\Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber
. That still needs to be moved.Comment #4
Wim Leers#2841027: JSON API format should only be used on JSON API routes, but can currently also be used for REST resources landed, one less blocker to this now!
Comment #5
Wim LeersComment #6
e0ipso#2829977: SerializableHttpException and Drupal\jsonapi\Error\* are not necessary was committed. This is now unblocked.
Comment #8
dawehnerHere is a reroll.
Comment #10
Wim LeersI'm afraid the rebase in #8 wasn't entirely correct. Thanks though :)
I think this one is.
Comment #11
dawehnerThank you wim!
Comment #13
Wim LeersApparently not enough yet. On it.
Comment #14
Wim LeersOh hah. #2857658: Get rid of ResourceResponseInterface is what's causing these 5 failures :) A very silly reroll. Removed all 6 occurrences.
Comment #15
dawehnerHa, so we have test coverage for that. Good to know
Comment #17
Wim LeersRestJsonApiUnsupported
(and its duplicate,RestJsonApiFormatUnsupported
).JsonApiFunctionalTest
andJsonApiFunctionalMultilingualTest
.\Drupal\Tests\jsonapi\Kernel\Controller\RequestHandlerTest
— despite me writing in #3 that that test coverage also still needed to be moved. Working on that now.Comment #18
Wim LeersFixed #17.3:
DRUPAL_ROOT
.\Drupal::logger()
).logger.channel.jsonapi
service yet does not define it. IOW: test coverage for the logging itself is missing. Not fixing that here, just adding the service, because I need it.Comment #21
Wim Leers100% of the remaining failures are now:
I was finally able to reproduce this! #2844046: REST Resource config entities do not respect the status (enabled/disabled) is causing this. It changed some test internals. This fixes it.
Comment #22
dawehnerAs an additional follow up this could be moved into its own subscriber
+1 for that. ALternative you could have injected the app root
Comment #23
Wim Leersdrupal_get_path()
also calls out to the container. So then a unit test would have to mock the container. This is simpler.Do we have a RTBC? :)
Comment #24
dawehnerI have one :)
Comment #25
e0ipsoWe have the request object in the response object. In the request object we have the route object. In the route object we have an attribute saying if the route is JSON API or not. More complex to describe than the actual code.
Responses to JSON API routes can be assumed to need schema validation (if assertions are enabled).
Can we create a follow up ticket to move the assertion to an onResponse subscriber?
Comment #26
Wim LeersFollow-up created: #2859207: Move Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber::validateResponse() to its own subscriber.
Comment #27
e0ipsoComment #29
Wim LeersThanks!