匹配路线时,似乎不尊重Route @Method注释

时间:2019-04-25 23:49:26

标签: symfony symfony4 symfony-routing

我了解在允许类似访问的路由时,路由的顺序很重要。

令我感到困惑的是为什么向此路由提交DELETE请求时,它是否与GET路由匹配,而不是忽略它并尝试下面的匹配方法?

    /**
     * @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

完整披露

我了解为什么它与严格基于模式的最顶层路线匹配

不要理解为什么这样做时访问方法会被忽略

因此,为了测试,我调整了将基于DELETE的路由上移到GET路由之上


    /**
     * @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);
    }

仅..当我尝试通过执行在浏览器中访问url的基本操作(因此,GET)来获取现有的非测试记录时,就会发生这种情况

enter image description here

还有,天哪,它曾经删除过该记录。

为什么访问方法会被忽略?

2 个答案:

答案 0 :(得分:2)

首先,请注意所使用的 SensioFrameworkExtraBundle 版本,因为 SensioFrameworkExtraBundle 中的@Method注释已被删除< / strong>最新版本。相反,Symfony @Route批注定义了一个方法选项来限制路由的HTTP方法:

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

但是对于您来说,如果您使用的是HTML表单和GET和POST以外的HTTP方法,则需要包含_method参数来伪造HTTP方法。

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

答案 1 :(得分:0)

我认为您必须添加路由名称,并且该名称必须唯一。

尝试以下方式:

/**
     * @Route("/{game}",name="api_remove")
     * @Method({"DELETE"})
     */
    public function remove(Request $request, Game $game) {
      ...
    }

    /**
     * @Route("/{game}",name="single_remove")
     * @Method({"GET"})
     */
    public function single(Request $request, GameSerializer $gameSerializer, Game $game) {
       ...
    }