Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 295813

Refactor REST routing to address its brittleness

$
0
0

Problem/Motivation

It's very hard to understand routing in the REST module, and it's very brittle, because:

  1. ResourceBase only sets _format for GET route, should also do so for POST/PATCH/DELETE routes.
  2. ResourceBase generates one route per method for POST/PATCH/DELETE, but one route per method+format for GET. This should be made consistent.
  3. ResourceBase generates individual GET routes for every available serialization format, not just the ones that are allowed by the configuration, and then ResourceRoutes::alter() removes those that are not acceptable by the configuration.
  4. ResourceBase sets _content_type_format for PATCH/POST, but it should actually also set _format.
  5. ResourceBase sets _content_type_format not to the allowed formats for that particular REST resource (as per the rest.settings configuration), but to all acceptable serialization formats, and then has validation for it in \Drupal\rest\RequestHandler::handle().
  6. ResourceRoutes::alter() is doing configuration verification.
  7. ResourceRoutes::alter() assumes _format has only ever one format listed, even though multiple can be listed. This blows up as soon as any custom @RestResource plugin specifies multiple formats, which it can by not using ResourceBase::routes().
  8. ResourceRoutes::alter() sets _csrf_request_header_token on all routes, including GET routes. This is harmless, but it causes extra, unnecessary computations on those requests. And it makes the route more confusing to debug.
  9. RequestHandler::handle() assumes _format is always set, and always has a single value — and in case it's not set, its ultimate solution is "just pick JSON". But it's not guaranteed to have a single value… nor does it even always have a value. And in fact, PATCH/POST routes do not have _format set. So any PATCH/POST request will actually result in a JSON response, even if you explicitly specify ?_format=xml!— fixed by #2662284: Return complete entity after successful PATCH
  10. Handling of 4xx responses is done in RequestHandler::handle() instead of in a KernelEvents::EXCEPTION event subscriber. This prevents Basic Auth 401 responses from being sent, and means REST has its own system in parallel to Symfony's/Drupal core's.— fixed by #2739617: Make it easier to write on4xx() exception subscribers + #2805281: ?_format=hal_json error responses are application/json, yet should be application/hal+json + #2813853: RequestHandler has its own error handling rather than leaving it to KernelEvents::EXCEPTION event subscribers

Clearly, this leaves us in a state where we keep finding bizarre bugs.

Proposed resolution

Refactor REST's routing for better maintainability.

Remaining tasks

  1. Find agreement.
  2. Do it.
  3. Review it.
  4. Commit it.

User interface changes

None.

API changes

None.

Data model changes

None.


Viewing all articles
Browse latest Browse all 295813

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>