tyesty/routing-annotation-reader

Controller class annotation reader for collecting routes

1.2.1 2018-06-08 13:19 UTC

This package is auto-updated.

Last update: 2024-04-24 04:00:24 UTC


README

This small class indexes all controller classes in a given set of directories and creates a list of routes out of the action methods.

To ensure that your controller action is indexed, simply add a bunch of docblock to your Controller classes and run the annotation reader.

Usage

  • In order to be indexed properly, your project must follow the psr-4 namespace convention and all controller classes must have the postfix Controller.
  • All action methods must have the postfix "Action" in order to be indexed properly
  • Then simply annotate the contoller/action routes in your class/method docblocks
  • For controller classes, add a @BaseRoute <YOUR_BASE_ROUTE> annotation to your class docblock.
  • For controller action methods, add a @Route [<METHOD>] <YOUR_METHOD_ROUTE> (<YOUR_METHOD_NAME>) annotation.
  • You can add middlewares for either all methods in a particular class or only for a specific method by adding a @Middleware <YOUR_MIDDLEWARE_CLASS> annotation.
  • Run the annotation reader as described in the example below. It will then search for controller classes in the given folders and will walk through all the action methods, fetch the docblock comments and create the route array for you.

Creating a Reader object

Parameter Type Default Description
$directories array [] List of directories that contain the controller classes. These directories are traversed recursively.
$route_log ?string null The log file in which the routing documentation shall be written. If set to null, then no documentation is generated. If $log_function is set, then this parameter will be ignored.
$log_function ?callable null A function/invokeable class that will be run after the routes have been determined. This can be used for literally everything, but the most common use case is autogenerated routing documentation. The only parameter of the callable is the current Reader object.

Example

<?php
namespace foobar\Controllers;

/**
 * Your class documentation here...
 *
 * @BaseRoute /foobar
 * @Middleware MyFirstMiddleware
 */
class FooController {

  /**
   * Your action documentation here
   *
   * @Route [GET] /test (testaction)
   * @Route [GET] /alternative/test (testaction-alt)
   */
  public function myTestAction(Request $request, Response $response): Response {
    // do something cool ;-)
    return $response;
  }

  /**
   * Your action documentation here
   *
   * @Route [POST] /test (test-post-action)
   * @Middleware MySecondMiddleware
   */
  public function myTestPostAction(Request $request, Response $response): Response {
    // do something cool ;-)
    return $response;
  }

}
<?php

require_once("vendor/autoload.php");

// initialize the reader with the base path to your controller classes
$reader = new tyesty\RoutingAnnotationReader\Reader(["src"]);
$reader->run();
print_r($reader->getRoutes());

will then output

Array
(
    [0] => Array
        (
            [method] => get
            [route] => /foobar/test
            [action] => foobar\Controllers\FooController:myTestAction
            [name] => testaction
            [middlewares] => [
              "MyFirstMiddleware"
            ]
        )

    [1] => Array
        (
            [method] => get
            [route] => /foobar/alternative/test
            [action] => foobar\Controllers\FooController:myTestAction
            [name] => testaction-alt
            [middlewares] => [
              "MyFirstMiddleware"
            ]
        )

    [2] => Array
        (
            [method] => post
            [route] => /foobar/test
            [action] => foobar\Controllers\FooController:myTestPostAction
            [name] => test-post-action
            [middlewares] => [
              "MyFirstMiddleware",
              "MySecondMiddleware"
            ]
        )

)

Options

Set Controller class postfix

In order to overwrite the default controller class name postfix, simply call

$reader->setClassPostfix("YourNewPostfix");

Set Action method postfix

In order to overwrite the default controller action method name postfix, simply call

$reader->setMethodPostfix("YourNewPrefix");

Log routes to a file

For logging the determined routes to a HTML file, just add a second parameter to the constructor in which you set the complete path to the logfile (including the filename). The annotation reader will then automatically write the logfile. Be aware that this will slow down the reading process, so please use this option only in development environments.

$reader = new Reader(["src", "somemore", "paths"], "/path/to/your/logfile.html");

Set cache folder (enables caching)

If you want to cache the determined routes, you can set the cache folder to the place where you want the cache file to be saved. This automatically enables the caching mechanism. Be aware that you have to manually take care of cache invalidation. Therefore this is not really recommended, it's better practise to have the Injection class take care of caching. Nonetheless, if you want to enable caching, simply do

$reader->setCacheFolder("/path/to/cache/folder");

Create a custom log processor

If you want to use a custom log processor than the built in (see "log routes to a file"), you can pass it to the constructor as a callable. This callable has to accept one parameter, the current Reader object. Inside this method/invokeable class you then have full access to the complete Reader object.

$reader = new Reader([...], null, function(Reader $reader) { /* do something */ });

Route injection

Inject routes to Slim application

In order to inject routes into your slim application, you can use the SlimRouter class with its static inject method. This method accepts four parameters:

Parameter Type Default Description
$reader tyesty\RoutingAnnotationReader\ReaderInterface The reader object
$app_name string "app" The variable name of the current Slim App object
$cache_folder ?string null The path to the cache folder. If null, then no cache is used
$cache_ttl int 60 The TTL for the cached routes. Defaults to 60
Example
$app = new \Slim\App($container);

SlimRouter::inject(
  new Reader(["src", "somemore", "paths"]),
  "app",
  "/path/to/cache/folder",
  60
);