The current class can be improved significantly in these ways:

  1. retrieves the serializer directly from the container (because ContainerAwareInterface), should instead be injected, because there's no measurable performance difference (see #2)
  2. Then we're no longer using ContainerAware(Interface|Trait), so we can remove them
  3. RequestHandler::handle() is a 60-line function in which a lot of things happen. Splitting it up into multiple helper methods that are each called would make it far more maintainable.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers created an issue. See original summary.

Wim Leers’s picture

Issue summary: View changes

The performance difference for point 2, measured with Page Cache turned off, best of 5, with testing this:

$ ab -c 1 -n 100 -H 'Authorization: Basic …' http://d8/node/1?_format=hal_json

There is no measurable difference. So then there is also no point in not injecting the serializer of course: better to do that, it's cleaner!

Point 2 was:

  1. retrieves the serializer directly from the container, but does so unconditionally — if it's only retrieved for those requests that need it, then its service and the many services it depends upon only need to be initialized when necessary, which improves performance

IS updated.

Wim Leers’s picture

FileSize
2.16 KB
5.29 KB

Now also fixing array() -> [].

Wim Leers’s picture

Issue summary: View changes
FileSize
5.16 KB
7.91 KB

RequestHandler::handle() is a 60-line function in which a lot of things happen. Splitting it up into multiple helper methods that are each called would make it far more maintainable.

dawehner’s picture

+++ b/core/modules/rest/src/RequestHandler.php
@@ -59,6 +56,28 @@ public static function create(ContainerInterface $container) {
+    $resource_config = RestResourceConfig::load($resource_config_id);

I don't see why this is a good change. It just gives you a fun time if you actually debug that.

retrieves the serializer directly from the container (because ContainerAwareInterface), should instead be injected, because there's no measurable performance difference (see #2)

+1

I think when the class was first introduced controllers did not had dependency injection yet.

array() to []

We have a dedicated issue to do that.

Then we're no longer using ContainerAware(Interface|Trait), so we can remove them

Nice

Wim Leers’s picture

I don't see why this is a good change. It just gives you a fun time if you actually debug that.

Huh? Isn't it the rule to use this whenever possible?

dawehner’s picture

I talked with alexpott and we certainly don't recommend it core. For custom/contrib code sure, whatever, but for core we prefer injection over everything else.

Wim Leers’s picture

Wim Leers’s picture

Title: [PP-1] Simplify RequestHandler » [PP-2] Simplify RequestHandler
Wim Leers’s picture

Title: [PP-2] Simplify RequestHandler » [PP-1] Simplify RequestHandler

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Wim Leers’s picture

Title: [PP-1] Simplify RequestHandler » [PP-2] Simplify RequestHandler
Wim Leers’s picture

Title: [PP-2] Simplify RequestHandler » [PP-1] Simplify RequestHandler

#2883680: Force all route filters and route enhancers to be non-lazy landed 2 months ago, ever since, we've only been blocked on #2858482: Simplify REST routing: disallow requesting POST/PATCH in any format, make consistent, which has received another ~80 comments since #13 (😮), but is now RTBC! 🎉

Wim Leers’s picture

Title: [PP-1] Simplify RequestHandler » Simplify RequestHandler: make it no longer ContainerAware, split up ::handle()
Assigned: Wim Leers » Unassigned
Issue summary: View changes
Status: Postponed » Needs review
FileSize
10.07 KB

Rebased #5.

Also: turns out this is no longer blocked on #2858482: Simplify REST routing: disallow requesting POST/PATCH in any format, make consistent! Earlier iterations of #2858482 were changing RequestHandler probably, but that's no longer the case.

Status: Needs review » Needs work

The last submitted patch, 15: 2853460-15.patch, failed testing. View results

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
1.25 KB
11.26 KB

I forgot to update the unit test. Easy-peasy.

gabesullice’s picture

+++ b/core/modules/rest/src/RequestHandler.php
@@ -60,22 +68,51 @@ public function __construct(EntityStorageInterface $entity_storage, ConfigFactor
+   *   The normalized request method.

Nit: "The normalized HTTP request method."

It took me a bit to realize this was not referring to class methods.


Otherwise, this looks really good!

Wim Leers’s picture

FileSize
954 bytes
11.27 KB

Done!

gabesullice’s picture

Status: Needs review » Reviewed & tested by the community

Awesome!

neclimdul’s picture

+++ b/core/modules/rest/src/RequestHandler.php
@@ -9,23 +9,21 @@
-class RequestHandler implements ContainerAwareInterface, ContainerInjectionInterface {
-
-  use ContainerAwareTrait;

is this an "interface" we have to deprecate? yuck. :-/

Wim Leers’s picture

I'm not sure what you're asking, @neclimdul?

neclimdul’s picture

I guess I'm asking how strict we're going to be about our BC. We're removing a public method by removing the trait. Its not a particularly useful or likely to be used interface but it is one.

Wim Leers’s picture

This is a controller, which doesn't have any BC guarantees: https://www.drupal.org/core/d8-bc-policy#controllers, so we're good :)

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/rest/src/RequestHandler.php
@@ -60,22 +68,51 @@ public function __construct(EntityStorageInterface $entity_storage, ConfigFactor
+    $resource_config_id = $route_match->getRouteObject()->getDefault('_rest_resource_config');
...
+    $resource_config = $this->resourceStorage->load($resource_config_id);

Shouldn't we be able to list this as an argument, and if properly named and type hinted then the controller resolver will upcast it? Or are you opting not to do that for some other reason (other than the naming $_rest_resoure_config which would suck). If so, should we document why?

Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community

No — things in a route definition's defaults are never upcasted. We're not changing the logic you're citing at all: we're just making sure clearly separate concerns are in separate methods, making the RequestHandler easier to understand, maintain, debug.

Proof this is just being moved:

+++ b/core/modules/rest/src/RequestHandler.php
@@ -60,22 +68,51 @@ public function __construct(EntityStorageInterface $entity_storage, ConfigFactor
+    $resource_config_id = $route_match->getRouteObject()->getDefault('_rest_resource_config');
+    /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */
+    $resource_config = $this->resourceStorage->load($resource_config_id);

@@ -89,18 +126,34 @@ public function handle(RouteMatchInterface $route_match, Request $request) {
-    $resource_config_id = $route_match->getRouteObject()->getDefault('_rest_resource_config');
-    /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */
-    $resource_config = $this->resourceStorage->load($resource_config_id);

Also, that'd be perfect to address in a follow-up, if it is indeed possible!

webchick’s picture

Status: Reviewed & tested by the community » Fixed

@Wim Leers walked me through this on Slack. As stated, this is just refactoring/moving around existing code to make it more maintainable.

I had the same question as @neclimdul in #23, and got the same answer as #24. :D And the fact that the only tests being changed here as a result of this patch are internal back up the fact that this is an internal API.

It looks like @larowlan's concerns are addressed at #26, and this patch is blocking file upload functionality in the REST API, which is pretty flippin' critical, soooo...

Committed and pushed to 8.5.x. Thanks!

  • webchick committed c1df3d2 on 8.5.x
    Issue #2853460 by Wim Leers, dawehner, gabesullice, neclimdul, larowlan...
Wim Leers’s picture

Yay, this already really helped: #1927648-501: Allow creation of file entities from binary data via REST requests shows that that this allows us to bring the number of changes in RequestHandler down from 140 lines to 60! (And each of the remaining changes is much, much simpler, no longer ambiguous.)

larowlan’s picture

Wim Leers’s picture

Thanks, @larowlan, and turns out that what you envisioned works, just not the upcasting bit (which is what I thought you meant and hence wrote#26). Already RTBC'd it :)

Status: Fixed » Closed (fixed)

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