PHPackages                             appserver-io/routlt - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. appserver-io/routlt

ActiveLibrary

appserver-io/routlt
===================

Servlet based micro router and controller implementation.

2.4.4(6y ago)36.5k↓100%4[2 issues](https://github.com/appserver-io/routlt/issues)OSL-3.0PHPPHP &gt;=5.4.0

Since Jul 11Pushed 6y ago2 watchersCompare

[ Source](https://github.com/appserver-io/routlt)[ Packagist](https://packagist.org/packages/appserver-io/routlt)[ Docs](https://github.com/appserver-io/routlt)[ RSS](/packages/appserver-io-routlt/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (12)Versions (39)Used By (0)

Rout.Lt 2
=========

[](#routlt-2)

[![Latest Stable Version](https://camo.githubusercontent.com/255c2b9b9160989eef8ec511732c9f519d23277633b95cae299250c860b380cd/68747470733a2f2f706f7365722e707567782e6f72672f6170707365727665722d696f2f726f75746c742f762f737461626c652e706e67)](https://packagist.org/packages/appserver-io/routlt)[![Total Downloads](https://camo.githubusercontent.com/2cb01af7a5992b859310dae3c6e384c65f2aaaa5e56d4028b31c6c844aebe389/68747470733a2f2f706f7365722e707567782e6f72672f6170707365727665722d696f2f726f75746c742f646f776e6c6f6164732e706e67)](https://packagist.org/packages/appserver-io/routlt)[![License](https://camo.githubusercontent.com/e430892fd3795aabfa88581137a682d9e2920a3b570d2a9b01421880f9e85823/68747470733a2f2f706f7365722e707567782e6f72672f6170707365727665722d696f2f726f75746c742f6c6963656e73652e706e67)](https://packagist.org/packages/appserver-io/routlt)[![Build Status](https://camo.githubusercontent.com/02092f0da06df7f033bcea1e078ee1a05686cd94b47ea88453c0c9973afcc100/68747470733a2f2f7472617669732d63692e6f72672f6170707365727665722d696f2f726f75746c742e706e67)](https://travis-ci.org/appserver-io/routlt)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/f8247fd5f10194e0a50dd3d004ec2ddda2882a182850983d5799bd287c6dce28/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6170707365727665722d696f2f726f75746c742f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/appserver-io/routlt/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/29455196beca99b0068479a41525822907fa86d15eff62723dd7c6bee89571f2/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6170707365727665722d696f2f726f75746c742f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/appserver-io/routlt/?branch=master)

Introduction
------------

[](#introduction)

Rout.Lt 2 provides a small, but very fast, implementation of a routing and controller implementation for usage with appserver.io based on a [servlet](http://appserver.io/get-started/documentation/servlet-engine.html).

Installation
------------

[](#installation)

If you want to write an application that uses Rout.Lt 2, you have to install it using Composer. To do this, simply add it to the dependencies in your `composer.json`

```
{
    "require": {
        "appserver-io/routlt": "~2.0"
    }
}
```

Configuration
-------------

[](#configuration)

Rout.Lt 2 comes with it's own annotations and configuration files.

### Application

[](#application)

Therefore, it is necessary, that these annotations as well as all other framework specific configuration files will be initialized on application startup. To ensure this, you have to provide a custom `META-INF/context.xml` file with your application, which needs the additional `` node for the object manager configuration

```

        ...

                AppserverIo\Description\ServletDescriptor
                AppserverIo\Description\MessageDrivenBeanDescriptor
                AppserverIo\Description\StatefulSessionBeanDescriptor
                AppserverIo\Description\SingletonSessionBeanDescriptor
                AppserverIo\Description\StatelessSessionBeanDescriptor
                AppserverIo\Routlt\Description\PathDescriptor

        ...

```

### Servlet Engine

[](#servlet-engine)

As Rout.Lt 2 is based on a servlet, you also need to provide an `WEB-INF/web.xml` your application.

Let's assume, you've installed appserver.io on Linux/Mac OS X under `/opt/appserver` and your application is named `myapp` you'll save the `web.xml` containing the following content in directory `/opt/appserver/myapp/WEB-INF`

```

    appserver.io example application
    This is the example application for the appserver.io servlet engine.

        my_login
        my_session_

        A servlet that handles DHTML files.
        The DHTML servlet
        dhtml
        AppserverIo\Appserver\ServletEngine\Servlets\DhtmlServlet

        The Rout.Lt 2 controller servlet implementation.
        The Rout.Lt 2 controller servlet
        routlt
        AppserverIo\Routlt\ControllerServlet

            action.namespace
            /MyApp/Actions

            routlt.configuration.file
            WEB-INF/routlt.properties

        dhtml
        *.dhtml

        routlt
        /

        routlt
        /*

```

Action Mapping
--------------

[](#action-mapping)

As Rout.Lt 2 provides annotations to configure routes and actions, the `routlt.json` configuration file, needed for version ~1.0, is not longer necessary nor supported.

### Using Annotations

[](#using-annotations)

You have two annotations, namely `@Path` and `@Action` to configure the routing of your application. These annotations give you the possibility to map the `Path Info` of a request to a method in an action class. This mechanism is adopted by many of the available frameworks. The `Path Info` segments will be separated by a slash. The first segment has to map to the value of the `@Path` annotations `name` attribute, the second to one of the `@Action` annotations of one of methods.

For example, assuming you want to dispatch the URL `http://127.0.0.1:9080/myapp/index.do/index/login`, you need the implementation of an action class that looks like this.

```
namespace MyApp\Actions;

use AppserverIo\Routlt\DispatchAction;
use TechDivision\Servlet\Http\HttpServletRequestInterface;
use TechDivision\Servlet\Http\HttpServletResponseInterface;

/**
 * Example action that shows the usage of the @Path annotation.
 *
 * @Path
 */
class IndexAction extends DispatchAction
{

    /**
     * Dummy action implementation that writes 'Hello World' to the response.
     *
     * @param \TechDivision\Servlet\Http\HttpServletRequestInterface  $servletRequest  The request instance
     * @param \TechDivision\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance
     *
     * @return void
     */
    public function indexAction(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
    {
        $servletResponse->appendBodyStream('Hello World!');
    }

    /**
     * Dummy action that shows the usage of the @Action annotation.
     *
     * @param \TechDivision\Servlet\Http\HttpServletRequestInterface  $servletRequest  The request instance
     * @param \TechDivision\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance
     *
     * @return void
     * @Action(name="/login")
     */
    public function loginToBackendAction(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
    {
        // do some login stuff here
    }
}
```

After saving the above code to a file named `/opt/appserver/webapps/myapp/WEB-INF/classes/MyApp/Actions/IndexAction.php` and [restarting](http://appserver.io/get-started/documentation/basic-usage.html#start-and-stop-scripts), open the URL `http://127.0.0.1:9080/myapp/index.do/index` with your favorite browser. You should see `Hello World!` there.

> If you don't specify the `name` attributes, depending on the annotation, Rout.Lt uses the class or the method name. As the `Action` suffix has to be cut off, it is important, that the action and the action methods always ends with `Action` and nothing else.

### Wildcards

[](#wildcards)

Up with version 2.2 you can also use wildcards in the `@Action` annotation's name attribute, e. g.

```
/**
 * Action to fetch an articles relation and return the result, e. g. as JSON API compatible result.
 *
 * @param \TechDivision\Servlet\Http\HttpServletRequestInterface  $servletRequest  The request instance
 * @param \TechDivision\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance
 *
 * @return void
 * @Action(name="/articles/:id/:relation")
 */
public function nameDoesntMatterAction(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
{
    // fetch an articles relation, e. g the author and return's the result
}
```

The values, mapped by the wildcards, are available, as usual request parameters, through the `$servletRequest->getParameter()` method, e. g.

```
/**
 * Action to fetch an articles relation and return the result, e. g. as JSON API compatible result.
 *
 * @param \TechDivision\Servlet\Http\HttpServletRequestInterface  $servletRequest  The request instance
 * @param \TechDivision\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance
 *
 * @return void
 * @Action(name="/articles/:id/:relation")
 */
public function nameDoesntMatterAction(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
{

    // load ID and relation
    $id = $servletRequest->getParameter('id', FILTER_VALIDATE_INT);
    $relation = $servletRequest->getParameter('relation');

    // fetch an articles relation, e. g the author and return's the result
}
```

### Restrictions

[](#restrictions)

Additionally to the wildcards it is possible to define restrictions for each wildcard like

```
/**
  * @Action(name="/articles/:id/:relation", restrictions={{"id", "\d+"}, {"relation", "\w+"}})
  */
```

If a restriction is defined, the variable is only mapped, if the restriction complies. The functionality behind the restrictions uses regular expressions to make sure, the passed value complies. Therefore, each restriction consist's of the wildcard name and the restriction term itself e. g. `{"id", "\d+"}`. The restriction term must be a valid regular expression term, like `\d+` that makes sure, that the value **MUST** be a digit. If no restriction has been set, Rout.Lt assumes that the passed value is a string and uses the defaul `\w+` term to check the consistency.

### Defaults

[](#defaults)

Beside the restrictions it is possible to define default values for wildcards, like

```
/**
  * @Action(
  *     name="/articles/:id/:relation",
  *     restrictions={{"id", "\d+"}, {"relation", "\w+"}},
  *     defaults={{"relation", "author"}}
  * )
  */
```

If the relation has not been given in the path info, like `/articles/3`, the default value `author` will be set and is available as request parameter then.

Action -&gt; Request Method Mapping
-----------------------------------

[](#action---request-method-mapping)

Sometimes it is necessary to allow action invocation only for selected request methods. For example, it has to be possible to configure the `indexAction()` only to be invoked on a `POST` request. To do this, you can add a @Post annotation to the methods doc block, like

```
/**
 * Dummy action implementation that writes 'Hello World' to the response.
 *
 * @param \TechDivision\Servlet\Http\HttpServletRequestInterface  $servletRequest  The request instance
 * @param \TechDivision\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance
 *
 * @return void
 * @Post
 */
public function indexAction(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
{
    $servletResponse->appendBodyStream('Hello World!');
}
```

Annotations are available for all request methods `CONNECT`, `DELETE`, `GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH` and `TRACE`. If you don't add one of the above annotations, an action will be invoked on **ALL** of the request methods.

> If you add one of them, the action will be invoked on that annotation only. On all other request methods, a `AppserverIo\Psr\Servlet\ServletException` with a `404` status code will be thrown, which results in a `404` error page.

Results
-------

[](#results)

By specifying results with the @Results annotation, a developer is able to specify a post processor, to process action results, e. g. by a template engine. By default, Rout.Lt 2 provides a servlet that uses simple DHTML files as templates and processes them in the scope of the servlet's `process()` method. This allows access to servlet request/response instances as well as servlet configuration parameters.

The following example uses a @Results annotation, which contains a nested @Result annotation, to process the `/path/to/my_template.dhtml` after invoking the `indexAction()` method.

```
namespace MyApp\Actions;

use AppserverIo\Routlt\DispatchAction;
use AppserverIo\Routlt\ActionInterface;
use TechDivision\Servlet\Http\HttpServletRequestInterface;
use TechDivision\Servlet\Http\HttpServletResponseInterface;

/**
 * Example action that shows the usage of the @Results annotation.
 *
 * @Path
 * @Results({
 *     @Result(name="input", type="AppserverIo\Routlt\Results\ServletDispatcherResult", result="/path/to/my_template.dhtml")
 * })
 */
class IndexAction extends DispatchAction
{

    /**
     * Dummy action implementation that writes 'Hello World' to the response.
     *
     * @param \TechDivision\Servlet\Http\HttpServletRequestInterface  $servletRequest  The request instance
     * @param \TechDivision\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance
     *
     * @return string The result identifier
     */
    public function indexAction(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
    {
        try {
            // add the Hello World! text to the request attributes
            $servletRequest->setAttribute('text', 'Hello World!');
        } catch (\Exception $e) {
            // add the exception to the error messages
            $this->addFieldError('fatal', $e->getMessage());
        }
        // return the result identifier for our template
        return ActionInterface::INPUT;
    }
}
```

It is possible to specify as many @Result annotations as necessary to support allow result processing in different use cases. Which result has to be used, depends on the string value, returned by your action.

The DHTML file, that has to be stored under `/path/to/my_template.dhtml` specified above will load the string, added as request attribute in the `indexAction()` method and renders it as a HTML document.

```
DOCTYPE html>

        Simple DHTML Servlet
