2017 © Pedro Peláez
 

library routes

image

webx/routes

  • Wednesday, November 15, 2017
  • by niclaslindberg
  • Repository
  • 1 Watchers
  • 2 Stars
  • 184 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 1 Forks
  • 0 Open issues
  • 63 Versions
  • 0 % Grown

The README.md

WebX-Routes - A PHP controller framework

Main features and design goals of webx-routes: * Simplicity - Easy to follow request/response routes to business logic in a natural hierarchical model. * Scalability - never load unnecessary files * Dependency injection (IOC) everywhere. * Testability - clear separation of view- and business objects by glueing it all together., (*1)

Getting started

In composer.json add:, (*2)

 {
    "require" : {
        "webx/routes" : "major.minor.patch"
    }
 }

Writing your first Routes index.php public/index.php

    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Response;

    require_once "../vendor/autoload.php"; // $_SERVER["DOCUMENT_ROOT"] points to 'public' folder.

    RoutesBootstrap::run(function(Response $response) {
        $response->typeJson([
            "user" =>
                ["name" => "Mr. Andersson"]
            ]
        ]);
        $response->data(1998,"user.popular"); //Merges the data into 'user.popular'
    });

Will generate JSON response:, (*3)

    {
        "user" : {
            "name" => "Mr. Andersson",
            "popular" => 1998
        }
    }

Built-in ResponseTypes in Routes

Routes supports the following ResponseTypes out of the box * JsonResponse Renders data as Json (Default ResponseType). * TemplateResponseType Renders data with a template (Twig) * RawResponseType Renders data as is. * DownloadResponseType Renders data as a downloadable file. * RedirectResponseType 301 or 302 redirect to a different url. * FileContentResponseType Sends a file's content to browser with auto detecting content-type., (*4)

Routing in Routes

    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Routes;
    use WebX\Routes\Api\Response;

    RoutesBootstrap::run(function(Routes $routes) {

        $routes->onSegment("api",function(Routes $routes) {

            $routes->onMatch("v(?P<version>\d+)$",function(Routes $routes,$version) {
                $routes->load("api_v{$version}");                      // $version from RegExp

            })->onAlways(Response $response) {
                $response->typeJson(["message"=>"Not a valid API call"]);
            });

        })->onAlways(function(Response $response){
            $response->typeRaw();
            $response->data("Sorry, page not found.");
            $response->status(404);

        })
    });

Routing in Routes - with url parameters example

    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Routes;
    use WebX\Routes\Api\Response;

    RoutesBootstrap::run(function(Routes $routes) {
        $routes->onAlways(function(Response $response, $myParam="default") {
            $response->typeRaw($myParam);
        }
    });

Will render: * hello for request on /hello * default for request on /, (*5)

Route switches:

Route switches are evaluated top-down. If a route-switch is executed no further switches, in same the scope, are evaluated and executed., (*6)

The following route switches are supported * onAlways($action) Executes without evaluation. * onTrue($expression,$action) Executes if $expression evaluates to true * onSegment("url-segment",$action) Evaluates the current url segment (complete url exploded by /). Within a route-switch match the current url-segment will advance one position. * onMatch("reg-exp",$action) Evaluates the reg-exp against a string (url is default). Matched parameters in the reg-exp will be used if the same variable name is used in the $action;, (*7)

Using Twig

page.twig, (*8)

    <html>
        <body>
            <h1>Welcome {{user.name}}</h1>
            Your input was {{input}}
        </body>
    </html>
    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Response;
    use WebX\Routes\Api\Request;

    RoutesBootstrap::run(function(Response $response, Request $request) {
          $response->typeTemplate()->id("page");
          $response->data(["name"=>"Mr. Andersson"],"user");
          $response->data($request->parameter("input"), "input");
    });

Reading input

Routes provides a unified and type-safe way to read request input from query parameters and json- form-encoded requests., (*9)

    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Response;
    use WebX\Routes\Api\Request;

    RoutesBootstrap::run(function(Response $response, Request $request) {
          $reader = $request->reader(Request::INPUT_AS_JSON);
          $response->typeJson(["greeting"=>"Hello, {$reader->asString("user.name")}"]);
    });

Configuring Twig

Load a configuration changetwig (can be any name) at Bootstrap time., (*10)

Example: To change Twigs tag-delimeters to {{{ and }}} (To simplify mixed Angular and Twig in the same page)., (*11)

    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Routes;
    use WebX\Routes\Api\Response;

    RoutesBootstrap::run([function(Routes $routes) {

        $routes->onAlways(function(Response $response) {
              $response->templateType()->id("page");
              $response->data(["name"=>"Mr. Andersson"],"user");
        })

    },"changetwig"]);

Override the setting for TemplateResponseType to add a configurator for Twig config/changetwig.php:, (*12)

    return [
        "responseTypes" => [
            "WebX\\Routes\\Api\\ResponseTypes\\TemplateResponseType" => [
                "config" => [
                    "configurator" => function(Twig_Environment $twig) {
                        $lexer = new Twig_Lexer($twig, array(
                            'tag_variable'  => array('{{{', '}}}')
                        ));
                        $twig->setLexer($lexer);
                    },
                    "options" => [    // Passed as second argument to Twig_Environment
                        "cache" => "/tmp/twig_cache"
                    ]
                ]
            ]
        ]
    ]

Loading configurations and the IOC container

All logic, in Routes, is executed in actions. An action can be either a: * \Closure * string (In format "ControllerClass#method"), (*13)

To support lazy loading of configurations Routes allows actions to be defined as an array in the format: [$action,"config1","config2","configN"], (*14)

src/MyBusiness/Impl/Services/AdminService.php, (*15)

    use MyBusiness\Api\Services\IAdminService;

    class AdminService implements IAdminService {
        public function __construct() {}

        public function countAdmins() {
            return 3;
        }
    }

config/admin.php:, (*16)

    use MyBusiness\Impl\Services\AdminService;

    return [
        "ioc" => [
            "register" => [
                [AdminService::class]
            ]
        ]
    ]
    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Routes;
    use WebX\Routes\Api\Response;
    use MyBusiness\Api\Services\IAdminService;

    RoutesBootstrap::run(function(Routes $routes) {

        $routes->onSegment("admin",[function(Response $response, IAdminService $adminService) {
              $response->data($adminService->countAdmins(),"count");
        },"admin"]);

        // The admin-configuration is only loaded if routes matched the `admin` segment.
    });

Config file anatomy

The config files, that may be loaded at any level, are normal php files that are expected to return an array., (*17)

Minimal config file (that does nothing):, (*18)


Ioc container

The WebX-Ioc container is embedded in the WebX-Routes framework. WebX-Routes supports dynamic registration / static invokation of services in the config ioc section., (*19)

Dynamically register a service with the WebX-Ioc container. config/someconfig.php, (*20)

<?php

return [
    "ioc" => [
        "register" => [ // The classes will be scanned for all their implemented interfaces.
            [MyClass:class],
            [MyOtherClass:class]
        ],
        "initStatic" => [ //
            [MyValueObject::class,"initMethod"] // The static "initMethod" will be invoked with declared dependencies.
        ]
    ],
    "mappings" => [
        "closureParameterName" => "iocInstanceId"
    ]

]

Working with Controllers

Routes support a more traditional controller structure as well. Controllers are simple classes with their methods and constructors invoked with IOC support., (*21)

Routes supports $action to be defined as a string in the format ControllerClass#method, (*22)

    use WebX\Routes\Api\RoutesBootstrap;
    use WebX\Routes\Api\Routes;

    RoutesBootstrap::run(function(Routes $routes) {

        $routes->onSegment("admin",['MyBusiness\\Controllers\\AdminCtrl','adminConfig']
        // The admin-configuration is only loaded if routes matched the `admin` segment. Methods on the
        // controller will automatically be mapped by the next available segment

        // If no next segment exist Routes will map the request to `index()` of the controller instance
    });

src/MyBusiness/Controllers/AdminController.php, (*23)


namespace MyBusiness\Controllers; class AdminController { private $logService; public function __construct(ILogService $logService) { $this->logService = $logService; } public function countAdmins(Response $response, RawResponseType $responseType, IAdminService $adminService) { $response->type($responseType); $response->data("Hello there " + $adminService->countAdmins() + " admin(s)"); } } #Controller functions can be invoked with user parameters. Parameters, taking precedence over IOC injected ones, #can be defined in the last arguemnt `$parameters` array or with parametes defiend in the `onMatch` switch.

Defining default namespaces for loading controllers

Full class names can be skipped by adding namespaces in the namespaces section of a dynamic configuration., (*24)

config/admin.php:, (*25)

    return [
        "namespaces" => ["MyBusiness\\Controllers"]
    ]

Creating your own ResponseType

To implement your own ResponseType simply create an interface that extends ResponseType with an implementation configure it with ioc/register in a config file. See bootstrap_config.php of how to configure., (*26)

Configuring your own ResponseType in your config file:, (*27)

    return [
        "responseTypes" => [
            "YourNamespace\\YourResponseTypeInterface" => [
                "class" => "YourNamespace\\YourResponseTypeClass",
                "config" => [
                    "yourSetting" => false // Will be available by Configuration to ResponseType.
                ]
            ]
        ]
    ]

Configuring Routes

Standard configuration in Routes is based on the applications directory relativly to the $_SERVER['DOCUMENT_ROOT']., (*28)

Configuring RoutesBootstrap, (*29)

    RoutesBootstrap::run($action,[
        "home" => "../"         // Default.
                                // Use '/' to have application in same directory
                                // as public files (not recommended).
    ]);

The default directory structure for a Routes application:, (*30)

    /
        /config          (Config files loaded by [$action, "someconfig"]
            someconfig.php

        /routes          (Files loaded by Routes->load("someroute")
            someroute.php

        /templates       (Templates loaded by TemplateResponse->setTemplate("sometemplate")
            sometemplate.twig

        /public          ($_SERVER['DOCUMENT_ROOT'])
            index.php

        /vendor          (Composer)
            /webx
                /routes
                /ioc

Tests

Execute in root directory, (*31)

    phpunit -c tests

The Versions

15/11 2017

dev-master

9999999-dev

  Sources   Download

MIT

The Requires

 

The Development Requires

15/11 2017

2.0.10

2.0.10.0

  Sources   Download

MIT

The Requires

 

The Development Requires

24/09 2017

2.0.9

2.0.9.0

  Sources   Download

MIT

The Requires

 

The Development Requires

24/09 2017

2.0.8

2.0.8.0

  Sources   Download

MIT

The Requires

 

The Development Requires

23/09 2017

2.0.7

2.0.7.0

  Sources   Download

MIT

The Requires

 

The Development Requires

23/09 2017

2.0.6

2.0.6.0

  Sources   Download

MIT

The Requires

 

The Development Requires

16/09 2017

2.0.5

2.0.5.0

  Sources   Download

MIT

The Requires

 

The Development Requires

12/09 2017

2.0.4

2.0.4.0

  Sources   Download

MIT

The Requires

 

The Development Requires

09/09 2017

2.0.3

2.0.3.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/06 2017

2.0.2

2.0.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/06 2017

2.0.1

2.0.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/06 2017

2.0.0

2.0.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

15/05 2017

dev-rework

dev-rework

  Sources   Download

MIT

The Requires

 

The Development Requires

27/12 2016

0.6.9

0.6.9.0

  Sources   Download

MIT

The Requires

 

The Development Requires

15/12 2016

0.6.8

0.6.8.0

  Sources   Download

MIT

The Requires

 

The Development Requires

29/11 2016

0.6.7

0.6.7.0

  Sources   Download

MIT

The Requires

 

The Development Requires

29/11 2016

0.6.6

0.6.6.0

  Sources   Download

MIT

The Requires

 

The Development Requires

25/11 2016

0.6.5

0.6.5.0

  Sources   Download

MIT

The Requires

 

The Development Requires

24/10 2016

0.6.4

0.6.4.0

  Sources   Download

MIT

The Requires

 

The Development Requires

24/10 2016

0.6.3

0.6.3.0

  Sources   Download

MIT

The Requires

 

The Development Requires

06/09 2016

0.6.2

0.6.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

08/08 2016

0.6.1

0.6.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

13/07 2016

0.6.0

0.6.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

12/07 2016

0.5.11

0.5.11.0

  Sources   Download

MIT

The Requires

 

The Development Requires

08/07 2016

0.5.10

0.5.10.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/07 2016

0.5.9

0.5.9.0

  Sources   Download

MIT

The Requires

 

The Development Requires

16/06 2016

0.5.8

0.5.8.0

  Sources   Download

MIT

The Requires

 

The Development Requires

16/06 2016

0.5.7

0.5.7.0

  Sources   Download

MIT

The Requires

 

The Development Requires

16/06 2016

0.5.6

0.5.6.0

  Sources   Download

MIT

The Requires

 

The Development Requires

09/06 2016

0.5.5

0.5.5.0

  Sources   Download

MIT

The Requires

 

The Development Requires

08/06 2016

0.5.4

0.5.4.0

  Sources   Download

MIT

The Requires

 

The Development Requires

02/05 2016

0.5.3

0.5.3.0

  Sources   Download

MIT

The Requires

 

The Development Requires

29/04 2016

0.5.2

0.5.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

29/04 2016

0.5.1

0.5.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

27/04 2016

0.5.0

0.5.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

08/04 2016

0.4.11

0.4.11.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/04 2016

0.4.10

0.4.10.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/04 2016

0.4.9

0.4.9.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/04 2016

0.4.8

0.4.8.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/04 2016

0.4.7

0.4.7.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/04 2016

0.4.6

0.4.6.0

  Sources   Download

MIT

The Requires

 

The Development Requires

07/04 2016

0.4.5

0.4.5.0

  Sources   Download

MIT

The Requires

 

The Development Requires

06/04 2016

0.4.4

0.4.4.0

  Sources   Download

MIT

The Requires

 

The Development Requires

05/04 2016

0.4.3

0.4.3.0

  Sources   Download

MIT

The Requires

 

The Development Requires

05/04 2016

0.4.2

0.4.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

05/04 2016

0.4.1

0.4.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

05/04 2016

0.4.0

0.4.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

01/04 2016

0.3.11

0.3.11.0

  Sources   Download

MIT

The Requires

 

The Development Requires

01/04 2016

0.3.10

0.3.10.0

  Sources   Download

MIT

The Requires

 

The Development Requires

01/04 2016

0.3.9

0.3.9.0

  Sources   Download

MIT

The Requires

 

The Development Requires

01/04 2016

0.3.8

0.3.8.0

  Sources   Download

MIT

The Requires

 

The Development Requires

01/04 2016

0.3.7

0.3.7.0

  Sources   Download

MIT

The Requires

 

The Development Requires

31/03 2016

0.3.6

0.3.6.0

  Sources   Download

MIT

The Requires

 

The Development Requires

31/03 2016

0.3.5

0.3.5.0

  Sources   Download

MIT

The Requires

 

The Development Requires

31/03 2016

0.3.4

0.3.4.0

  Sources   Download

MIT

The Requires

 

The Development Requires

30/03 2016

0.3.3

0.3.3.0

  Sources   Download

MIT

The Requires

 

The Development Requires

30/03 2016

0.3.2

0.3.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

29/03 2016

0.3.1

0.3.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

29/03 2016

0.3.0

0.3.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

29/03 2016

0.2.0

0.2.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

25/03 2016

0.1.2

0.1.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

24/03 2016

0.1.1

0.1.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

24/03 2016

0.1.0

0.1.0.0

  Sources   Download

The Requires

 

The Development Requires