3

I know that there are discussions of what are the best practices for handling routes in Symfony2 (routing.yml vs annotations). Just let me mention, that I want to keep the way it is, using annotations.

When I define multiple routes for a single action in a controller, it seems, that the last definition of @Method annotations overrides all the other and thats why I'm getting the following error:

No route found for "POST /index": Method Not Allowed (Allow: GET, HEAD)

This is just a short snippet of code I'm using.

namespace MySelf\MyBundle\Controller;

use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

class MyController extends Controller{

    /**
     * @Route(
     *     "/index",
     *     name="index_default"
     * )
     * @Method({"GET", "POST"})
     *
     * @Route(
     *     "/index/{id}",
     *     name="index",
     *     requirements={
     *          "id": "\d+"
     *     }
     * )
     * @Method({"GET"})
     *
     * @return Response
     */
     public function indexAction($id = null){
          /*DO SOME FANCY STUFF*/
          ...
          return $response;
     }
}

whilest this is working very well!

index_default:
    pattern: /index
    defaults: { _controller: MyBundle:MyController:index }
    requirements:
      _method: GET|POST

index:
    pattern: /index/{id}
    defaults: { _controller: MyBundle:MyController:index }
    requirements:
      _method: GET
      id: \d+

Any idea to implement it the way it is working with routing.yml using annotations instead?

nTOXIC
  • 143
  • 2
  • 12
  • 1
    Try to specify the method in the route annotation directly (methods="GET|POST") – rpg600 Apr 17 '15 at 12:46
  • Thanks, that does exactly what I hoped to get :) Just post it as a separate answer, so I can tick this :) – nTOXIC Apr 17 '15 at 13:55

2 Answers2

5

You should specify the methods in each route annotation, @Method must be declared only once. In fact each type of annotation are handled separately, they are not aware of each others.

/**
 * @Route(
 *     "/index",
 *     name="index_default",
 *     methods="GET|POST"
 * )
 *
 * @Route(
 *     "/index/{id}",
 *     name="index",
 *     requirements={
 *          "id": "\d+"
 *     },
 *     methods="GET"
 * )
 *
 * @return Response
 */
rpg600
  • 2,800
  • 18
  • 24
0

I don't think it's possible to declare a @route or @Method annotation twice. You could create a default value for $id like this:

/**
 * @Route(
 *     "/index/{id}",
 *     name="index",
 *     requirements={
 *          "id": "\d+"
 *     },
 *     defaults={"id" = null}
 * )
 *
 * @Method({"GET", "POST"})
 *
 * @return Response
 */
public function indexAction($id)
{
    /*DO SOME FANCY STUFF*/
      ...
      return $response;
}

[edit] Ok, actually it is possible to declare multiple routes in the annotation. However, I don't think you should declare the @Method again. I'm not sure about this, but it seems that this:

@Method({"GET"})

is overriding this:

@Method({"GET", "POST"})

And when you override it, you're only left with GET. Remove the annotation that only declares GET and it should work.

Scuba Kay
  • 2,004
  • 3
  • 26
  • 48
  • It is possible to declare multiple routes! I'm using also annotations with 4 routes on a single action and they are all working as expected. The snipped is just an example! – nTOXIC Apr 17 '15 at 12:50
  • Well, I think this does what you want to achieve right? Also, why would you need multiple routes to the same action? It seems unnecessary to me. – Scuba Kay Apr 17 '15 at 12:55
  • 1
    And I would personally split up the methods. There's a programming best practice that states: "a method should do one thing and one thing only". Taking this into account you should have one method for posting an item, one for the index and one for reading a single item. – Scuba Kay Apr 17 '15 at 13:00
  • 1
    I know the rules of Clean Code and that is what I want to achieve, but it is to complicated to explain why I'm currently needing this approach. Later this thing needs to be fixed, but there is more serious work to do than this issue. Nevertheless, thanks for your advice :) – nTOXIC Apr 17 '15 at 13:38