/silex-annotation-provider

A Silex ServiceProvider that defines annotations that can be used to define routes in a ServiceController.

Primary LanguagePHPMIT LicenseMIT

Latest Stable Version Build Status Total Downloads License Scrutinizer Code Quality

silex-annotation-provider

A Silex ServiceProvider that defines annotations that can be used in a Silex controller. Define your controllers in a class and use annotations to setup routes and define modifiers.

Changes in v3

  • Redesigned annotation format. No more Doctrine Annotations.
  • Uses PSR-16 cache instead of Doctrine Cache.
  • Simplified feature set. Removes support for ServiceProviders, custom Service Controller registration, and other obscure customization options in favor of simplicity.
  • Minimum PHP version is now 7.1. No official support for HHVM.

Installation

Install the silex-annotation-provider using composer.

{
    "require": {
        "ddesrosiers/silex-annotation-provider": "~3.0"
    }
}

Registration

$app->register(new DDesrosiers\SilexAnnotations\AnnotationServiceProvider(), array(
    "annot.cache" => new MyPsr16Cache(),
    "annot.controllerDir" => "$srcDir/Controller",
    "annot.controllers" => [
        MyClass1::class,
        MyClass2::class
    ]
));

Parameters

annot.controllerDir

Specify the directory in which to search for controllers. This directory will be searched recursively for classes with the @Controller annotation. Found controller classes will be processed for route annotations. Either this or annot.controllers is required to locate controllers.

annot.controllers

An array of fully qualified controller names. If set, the provider will automatically register each controller as a ServiceController and set up routes and modifiers based on annotations found.

annot.cache

An instance of a class that implements Psr\SimpleCache\CacheInterface. This cache is used to cache annotation and the controller list to improve performance.

Faster Controller Registration

Silex has to register every endpoint in your app on every request. If you have a lot of endpoints, that could be a significant overhead on each and every request. Silex Annotations can improve this by filtering the controllers that need to be registered using the prefix on the Controller annotation. We only need to register the endpoints in the Controller if the prefix matches the URI. In this way, Silex Annotations allows FASTER routing than pure Silex.

Annotate Controllers

Create your controller. The following is an example demonstrating the use of annotations to register an endpoint.

namespace DDesrosiers\Controller;

use Symfony\Component\HttpFoundation\Response;

/**
 * @Controller(
 *     prefix => test
 *     after => \DDesrosiers\Controller\TestController::converter
 *     host => www.test.com
 *     requireHttp
 *     secure => ADMIN
 * )
 */
class TestController
{
    /**
     * @Route(
     *     uri => GET test/{var}
     *     assert => var, \d+
     *     convert => var, \DDesrosiers\Controller\TestController::converter
     *     after => \DDesrosiers\Controller\TestController::converter
     *     host => www.test.com
     *     requireHttps
     *     secure => DEV
     *     value => var, default
     * )
     */
    public function testMethod($var)
    {
        return new Response("test Method: $var");
    }

    public static function converter($var)
    {
        return $var;
    }
}

The annotations in our TestController are interpreted as follows:

$controllerCollection = $app['controller_factory']
    ->after('\DDesrosiers\Controller\TestController::converter');
    ->host('www.test.com');
    ->requireHttp();
    ->secure('ADMIN');
$controllerCollection->get("test/{var}", "\\DDesrosiers\\Controller\\TestController:testMethod")
    ->assert('var', '\d+')
    ->convert('var', "\\DDesrosiers\\Controller\\TestController::converter");
    ->host('www.test.com')
    ->requireHttps()
    ->secure('DEV')
    ->value('var', 'default');
$app->mount('/prefix', $controllerCollection);

Annotations

Controller

The @Controller annotation marks a class as a controller. The 'prefix' option defines the mount point for the controller collection. The prefix must be the first option.

@Route

The @Route annotation defines an endpoint. 'uri' is required and must be the first option defined.

Short Annotation Notation

In the Controller annotation, if prefix is the only option needed, the 'prefix' key can be omitted.

In the Route annotation, if uri is the only option needed, the 'uri' key can be omitted.

   namespace DDesrosiers\Controller;
   
   use Symfony\Component\HttpFoundation\Response;
   
   /**
    * @Controller(test)
    */
   class TestController
   {
       /**
        * @Route(GET test/{var})
        */
       public function testMethod($var)
       {
           return new Response("test Method: $var");
       }
   }