Search code examples
symfonysymfony4symfony-routing

Route @Method annotation doesn't seem to get respected when matching routes


I understand when allowing similarly accessible routes, that the order of the routes matter.

Where I'm confused is why when submitting a DELETE request to this route, does it match to the GET route, instead of ignoring it and trying the matched method one below it?

    /**
     * @Route("/{game}")
     * @Method({"GET"})
     */
    public function single(Request $request, GameSerializer $gameSerializer, Game $game) {
        $out = $gameSerializer->bind($game);
        return new JsonResponse($out);
    }

    /**
     * @Route("/{game}")
     * @Method({"DELETE"})
     */
    public function remove(Request $request, Game $game) {
        $em = $this->getDoctrine()->getManager();


        $em->remove($game);
        $em->flush();

        return new JsonResponse([], 200);
    }

enter image description here

enter image description here

Full disclosure

I understand why it matches the top most route based on strictly patterns

I dont understand why the access method is getting ignored when doing so

So, just to test, I adjusted to move the DELETE based route up above the GET route


    /**
     * @Route("/{game}")
     * @Method({"DELETE"})
     */
    public function remove(Request $request, Game $game) {
        $em = $this->getDoctrine()->getManager();

        $em->remove($game);
        $em->flush();

        return new JsonResponse([], 200);
    }

    /**
     * @Route("/{game}")
     * @Method({"GET"})
     */
    public function single(Request $request, GameSerializer $gameSerializer, Game $game) {
        $out = $gameSerializer->bind($game);
        return new JsonResponse($out);
    }

only.. for this to happen when I tried getting an existing non-test record by performing a basic operation of visiting the url in a browser (so, GET)

enter image description here

and oh boy, did it ever delete that record.

Why is the Access Method being ignored?


Solution

  • First of all, careful of which SensioFrameworkExtraBundle version you are using because the @Method annotation from SensioFrameworkExtraBundle has been removed in latest version. Instead, the Symfony @Route annotation defines a methods option to restrict the HTTP methods of the route:

    *
    * @Route("/show/{id}", methods={"GET","HEAD"})
    *
    

    But in your case, if you're using HTML forms and HTTP methods other than GET and POST, you'll need to include a _method parameter to fake the HTTP method.

    See How to Change the Action and Method of a Form for more information.