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->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
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
Created this issue to surface the problem and proposed solution. Feel free to improve upon it as needed.