DELETE request on REST resource leads to null format given

Created on 2 November 2023, 12 months ago
Updated 3 November 2023, 12 months ago

Problem/Motivation

This issue is a rehash of something another user reported in the Drupal forums: https://www.drupal.org/forum/support/module-development-and-code-questions/2023-08-30/http-delete-on-restapi-resource-leads-to-null-format-in .

The original post content is below:

Hello,

I developped a module having as goal to to let's say the basic CRUD operations.

For instance the GET (corresponding to read) is OK, POST (create) is OK and now, for DELETE, I'm face to an error that I've analysed but no reason found yet.

Details about my rest api implementation:

This is my uri_path:

uri_paths = {
*     "canonical" = "/rest/api/plateforme/entity/{type}/{id}",
*     "create" = "/rest/api/create",
*   }

I use "create" for POST and "canonical" for GET, DELETE and for UPDATE (once DELETE is working well).

The URL I use in Postman for delete is the following (the goal is to delete the entity of type "toy" with the id = 2:

http://drupal-local.dev/rest/api/plateforme/entity/toy/2?_format=json

When performing the request from Postman, I'm correctly get into my delete method and I retrieve the two params: toy and id = 2. I do my delete and at the end, I want to send back a json (also as for POST and GET) with some information about the DELETE result.

The error I get is the following:

em class="placeholder">TypeError</em>:
Symfony\Component\Serializer\Encoder\ChainEncoder::getEncoder(): Argument #1 ($format) must be of type string, null
given, called in symfony\serializer\Encoder\ChainEncoder.php on line 49 in <em class="placeholder">Symfony\Component\Serializer\Encoder\ChainEncoder-&gt;getEncoder()

However, I specify the _format=json in the URL and also, I've added a ContentType when creating the response:

$resp = new ResourceResponse(['message' => 'Entity deleted successfully.'], 200, ['Content-Type' => 'application/json']);
return $resp;

For testing purpose, I simplified everything for understanding the problem origin and what I might be doing wrong.

I even created the response and returned it at the beginning of the delete method but I still have the same error.

Analysing what's happening in Drupal Core, I found that in core\modules\rest\src\EventSubscriber

<?php
public function getResponseFormat(RouteMatchInterface $route_match, Request $request) {
  $route = $route_match->getRouteObject();
  $acceptable_response_formats = $route->hasRequirement('_format') ? explode('|', $route->getRequirement('_format')) : [];
  $acceptable_request_formats = $route->hasRequirement('_content_type_format') ? explode('|', $route->getRequirement('_content_type_format')) : [];
  $acceptable_formats = $request->isMethodCacheable() ? $acceptable_response_formats : $acceptable_request_formats;
I have $acceptable_request_formats and $acceptable_formats empty arays and this is because the call

$route = $route_match->getRouteObject();
?>

leading to core\lib\Drupal\Core\Routing\

<?php
protected function getRouteMatch(Request $request) {
  if (isset($this->routeMatches[$request])) {
    $route_match = $this->routeMatches[$request];
  }
  else {
    $route_match = RouteMatch::createFromRequest($request);
?>

goes via else and do not retrieve the expected json format.

I've made a comparative analysis between the DELETE and the POST and I found that for POST also the first call to getRouteMatch goes via else but all the subsequent calls will follow the 'if' statement and will have the json format well specified. For DELETE request, there is only one getRouteMatch call and it goes via else, so no json format.

I really don't understand what I'm doing wrong...

I'm in Drupal 9.5.9 version.

I appreciate any advice solving my problem.

Thank you all,

Grizou

Steps to reproduce

In my own separate project, we were getting this same error and were able to resolve it by making edits to the file: core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php

Proposed resolution

Created this issue to surface the problem and proposed solution. Feel free to improve upon it as needed.

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
REST 

Last updated 4 days ago

Created by

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024