ZetCode

Symfony @Route annotation

last modified July 5, 2020

Symfony @Route annotation tutorial shows how to create routes with @Route annotation in Symfony.

Symfony

Symfony is a set of reusable PHP components and a PHP framework for web projects. Symfony was published as free software in 2005. Fabien Potencier is the original author of Symfony. Symfony was heavily inspired by the Spring Framework.

@Route annotation

A route is a map from a URL path to a controller. For instance, the /about URL is mapped to the MyController's about() method.

The @Route annotation is used to create routes. Other options are XML and YAML configuration files and PHP code. The annoation is used inside the documentation string.

Symfony @Route example

In the following example, we use various options of @Route.

$ composer create-project symfony/skeleton routeanno
$ cd routeanno

With composer, we create a new Symfony skeleton project. We navigate to the project directory.

$ composer require maker
$ composer require annotations

We install two modules: annotations and maker. The @Route is defined in the annotations module.

$ composer require server --dev

We install the development web server.

$ php bin/console make:controller MyController

A MyController is created.

src/Controller/MyController.php
<?php

namespace App\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class MyController extends AbstractController
{
    /**
     * @Route("/home")
     */
    public function home()
    {
        return new Response("home",  Response::HTTP_OK,
            ['content-type' => 'text/plain']);
    }

    /**
     * @Route("/about", methods={"GET", "POST"})
     */
    public function about(Request $request)
    {
        $method = $request->getRealMethod();
        $msg = "about: " . $method;

        return new Response($msg,  Response::HTTP_OK,
            ['content-type' => 'text/plain']);
    }    

    /**
     * @Route("/news/{id}", requirements={"page"="\d+"})
     */
    public function news($id)
    {
        $msg = 'News ' . $id;

        return new Response($msg,  Response::HTTP_OK,
            ['content-type' => 'text/plain']);
    }    
}

MyController has three routes created with @Route.

/**
* @Route("/home")
*/
public function home()
{
    return new Response("home",  Response::HTTP_OK,
        ['content-type' => 'text/plain']);
}

Here we map the /home path to the home() method.

/**
* @Route("/about", methods={"GET", "POST"})
*/
public function about(Request $request)
{
    $method = $request->getRealMethod();
    $msg = "about: " . $method;

    return new Response($msg,  Response::HTTP_OK,
        ['content-type' => 'text/plain']);
}

With the methods option, we can restrict the requests to the specified method types. In our case, the about() method is only called for GET and POST requests.

/**
* @Route("/news/{id}", requirements={"page"="\d+"})
*/
public function news($id)
{
    $msg = 'News ' . $id;

    return new Response($msg,  Response::HTTP_OK,
        ['content-type' => 'text/plain']);
}

With the requirements option, we specify the allowed characters for the URL path. The {id} is a placeholder for integer values.

It is also possible to place the annotation on the controller class. This works as a prefix for all route paths.

$ php bin/console make:controller TestController

We create a new controller.

src/Controller/TestController.php
<?php

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

/**
 * @Route("/test")
 */
class TestController extends AbstractController
{
    /**
     * @Route("/car")
     */
    public function car()
    {
        $msg = 'Testing car';

        return new Response($msg,  Response::HTTP_OK,
            ['content-type' => 'text/plain']);
    }

    /**
     * @Route("/book")
     */
    public function book()
    {
        $msg = 'Testing book';

        return new Response($msg,  Response::HTTP_OK,
            ['content-type' => 'text/plain']);
    }
}

The TestController is annotated with @Route("/test"). Therefore, the URL paths will be /test/car and /test/book.

$ php bin/console debug:router
--------------- ---------- -------- ------ ------------
Name            Method     Scheme   Host   Path
--------------- ---------- -------- ------ ------------
app_my_home     ANY        ANY      ANY    /home
app_my_about    GET|POST   ANY      ANY    /about
app_my_news     ANY        ANY      ANY    /news/{id}
app_test_car    ANY        ANY      ANY    /test/car
app_test_book   ANY        ANY      ANY    /test/book
--------------- ---------- -------- ------ ------------

We can list the created routes with bin/console debug:router command.

Running the example

We start the server and test the created routes with the curl tool.

$ php bin/console server:run

We start the development server.

$ curl localhost:8000/home
home
$ curl -X POST localhost:8000/about
about: POST
$ curl localhost:8000/news/34
News 34
$ curl localhost:8000/test/car
Testing car
$ curl localhost:8000/test/book
Testing book

We generate requests with curl.

In this tutorial we have created routes in Symfony using @Route annotation.

List all Symfony tutorials.