Skip to content

Documentation v0.1

Alex Ash edited this page Mar 31, 2016 · 4 revisions

Installation

You need composer to install library:

composer require alexash-php/traveler:^0.1

Getting started

Use this in your bootstrap:

// Namespace of your controllers
$namespace     = 'Controllers\\Space';
$configuration = \Traveler\Bootstrap\configure($namespace);
$router        = \Traveler\Bootstrap\bootstrap($configuration)->get('Traveler\\Router');

And this, when you ready for routing (basic routing):

use Zend\Diactoros\Uri;

// These http method and uri are here for sake of example,
// it's up to you, how to get them (superglobals, PSR7 abstractions, etc.)
$httpMethod = 'GET';
$uri = new Uri('http://example.com/foo/bar/?a=baz&b=qux');

// Get Controller invoker
$invoker = $router->route($uri, $httpMethod);

// Invoke controller Controllers\Space\FooController::getBar('baz', 'qux')
// and obtain result
$result = $invoker();

Mapping examples:

GET /foo/bar/?a=baz&b=qux -> Controllers\Example\FooController::getBar('baz', 'qux')

GET /foo/?a=baz&b=qux -> Controllers\Example\FooController::getDefault('baz', 'qux')

GET /?a=baz&b=qux -> Controllers\Example\DefaultController::getDefault('baz', 'qux')

INVALIDMETHOD /foo/bar/?a=baz&b=qux -> throws DomainException

Default supported http methods are: 'GET', 'HEAD', 'POST', 'PATCH', 'PUT', 'DELETE', 'LINK', 'UNLINK', 'OPTIONS'

Advanced usage

You can use uri path to choose controller namespace (namespaced routing):

$httpMethod = 'GET';
$uri = new Uri('http://example.com/subspace/foo/bar/?a=baz&b=qux');

$invoker = $router->route($uri, $httpMethod);

// Invoke controller Controllers\Space\Subspace\FooController::getBar('baz', 'qux')
// and obtain result
$result = $invoker();
$httpMethod = 'GET';
$uri = new Uri('http://example.com/hyperspace/lightspeed/foo/bar/?a=baz&b=qux');

$invoker = $router->route($uri, $httpMethod);

// Invoke controller Controllers\Space\Hyperspace\Lightspeed\FooController::getBar('baz', 'qux')
// and obtain result
$result = $invoker();

You can also make use of multiword uri path segments (composite routing):

// In your bootstrap
$namespace     = 'Controllers\\Space';
$configuration = \Traveler\Bootstrap\configureComposite($namespace)
$router        = \Traveler\Bootstrap\bootstrap($configuration)->get('Traveler\\Router');

// ...

// Ready for routing
$httpMethod = 'GET';
$uri = new Uri('http://example.com/hyper-space/foo-bar/baz-qux/?a=earth&b=moon');

$invoker = $router->route($uri, $httpMethod);

// Invoke controller Controllers\Space\HyperSpace\FooBarController::getBazQux('earth', 'moon')
// and obtain result
$result = $invoker();

For projects organized as a hierarchy of packages (hierarchical routing):

// In your bootstrap

// Namespace for root packages
$namespace        = 'Root\\Space';
// Namespace offset between package and subpackages
subpackageOffset  = 'Subpackages';
// Namespace offset between package and controllers
$controllerOffset = 'Controllers';

$configuration    = \Traveler\Bootstrap\configureHierarchical(
    $namespace,
    $subpackageOffset,
    $controllerOffset
);
$router           = \Traveler\Bootstrap\bootstrap($configuration)->get('Traveler\\Router');

// ...

// Ready for routing
$httpMethod = 'GET';
$uri = new Uri('http://example.com/weather/cloud-heavy/example/action/?a=foo&b=bar');

$invoker = $router->route($uri, $httpMethod);

// Invoke controller
// Root\Space\Weather\Subpackages\CloudHeavy\Controllers\ExampleController::getAction('foo', 'bar')
// and obtain result
$result = $invoker();
// Ready for routing
$httpMethod = 'GET';
$uri = new Uri('http://example.com/cloud-heavy/example/action/?a=foo&b=bar');

$invoker = $router->route($uri, $httpMethod);

// Invoke controller Root\Space\CloudHeavy\Controllers\ExampleController::getAction('foo', 'bar')
// and obtain result
$result = $invoker();
// Ready for routing
$httpMethod = 'GET';
$uri = new Uri('http://example.com/example/action/?a=foo&b=bar');

$invoker = $router->route($uri, $httpMethod);

// Invoke controller Root\Space\Controllers\ExampleController::getAction('foo', 'bar')
// and obtain result
$result = $invoker();

Subpackages nesting level are not limited by router.

If you have several namespaces, under which controller could be found (multinamespaced routing):

// In your bootstrap

// Multiple namespaces can be used with every routing type
// Basic routing here for sake of simplicity
$namespace       = 'Controllers\\Space';
$extraNamespaces = ['Rulers\\Area', 'Birds\\Sky'];
$configuration   = \Traveler\Bootstrap\configure($namespace, $extraNamespaces);
$router          = \Traveler\Bootstrap\bootstrap($configuration)->get('Traveler\\Router');

// ...

$httpMethod = 'GET';
$uri = new Uri('http://example.com/foo/bar/?a=baz&b=qux');

// Get Controller invoker
$invoker = $router->route($uri, $httpMethod);

// Invoke controller Controllers\Space\FooController::getBar('baz', 'qux') or (if absent)
// Rulers\Area\FooController::getBar('baz', 'qux') or (if absent)
// Birds\Sky\FooController::getBar('baz', 'qux')
// and obtain result
$result = $invoker();

Modification

For tweaking router assembling with DI container look at bootstrap/bootstrap.php - take one of configure, configureComposite, or configureHierarchical and modify it for your needs:

  • Change wired realizations - for some interfaces there are more than one, and you can provide your own
  • Change/add constructor parameters
Clone this wiki locally