core/modules/rest/src/Plugin/ResourceBase.php | 4 +++- core/modules/rest/src/RequestHandler.php | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/modules/rest/src/Plugin/ResourceBase.php b/core/modules/rest/src/Plugin/ResourceBase.php index e91afd9..a53208c 100644 --- a/core/modules/rest/src/Plugin/ResourceBase.php +++ b/core/modules/rest/src/Plugin/ResourceBase.php @@ -131,9 +131,11 @@ public function routes() { $format_route = clone $route; $format_route->addRequirements(['_format' => $format_name]); + // Also allow this method to handle POST requests, so we can send + // 409 responses for already-existing resources. $methods = $route->getMethods(); $methods[] = 'POST'; - $route->setMethods($methods); + $format_route->setMethods($methods); $collection->add("$route_name.$method.$format_name", $format_route); } break; diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php index aea0509..9d04f98 100644 --- a/core/modules/rest/src/RequestHandler.php +++ b/core/modules/rest/src/RequestHandler.php @@ -74,7 +74,15 @@ public function handle(RouteMatchInterface $route_match, Request $request) { // @see \Symfony\Component\Routing\Matcher\UrlMatcher::matchCollection() // @see \Symfony\Component\HttpFoundation\Response::prepare() $method = strtolower($route_match->getRouteObject()->getMethods()[0]); - assert(count($route_match->getRouteObject()->getMethods()) === 1); + if ($method !== 'get') { + assert(count($route_match->getRouteObject()->getMethods()) === 1); + } + // REST resources' "GET" routes also support POST, to be able to throw a + // \Symfony\Component\HttpKernel\Exception\ConflictHttpException. + // @see \Drupal\rest\Plugin\ResourceBase::routes() + else { + assert($route_match->getRouteObject()->getMethods() === ['GET', 'POST']); + } $resource_config_id = $route_match->getRouteObject()->getDefault('_rest_resource_config');