Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Commit

Permalink
Initial docs for rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
Xerkus committed Nov 22, 2017
1 parent c8f96ef commit f6e49ca
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 80 deletions.
2 changes: 1 addition & 1 deletion docs/book/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="jumbotron">
<h1>zend-router</h1>

<p>Flexible routing system for HTTP and console applications.</p>
<p>Flexible routing system for PSR-7 HTTP applications.</p>

<pre><code class="language-bash">$ composer require zendframework/zend-router</code></pre>
</div>
Expand Down
64 changes: 64 additions & 0 deletions docs/book/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Introduction

zend-router is a HTTP router implementation for
[PSR-7 HTTP message interfaces](http://www.php-fig.org/psr/psr-7/).
It provides dynamic routing capabilities required in most modern web
applications using literal and dynamic path segments, domain, method and scheme
matching.

## Routing

Routing refers to matching request URI or other request information using
defined rules(routes) in order to determine an appropriate handler for the
request and to extract matched values.

Zend-router defines `match()` method that accepts PSR-7 server request and
returns `Zend\Router\RouteResult` instance to indicate the result of the
matching operation.

`RouteResult` provides three methods to check the outcome:
- `isSuccess()` will be true when route successfully matched
- `isFailure()` will be true when none of the routes matched
- `isMethodFailure()` will be true when some routes could match but with
different HTTP method. List of allowed HTTP methods is also provided with
`getAllowedMethods()`

## Retrieving matched parameters

When routing is successful, result will contain list of matched or default
parameters:

```php
$parameters = $result->getMatchedParams();
```

Typically, application utilizing zend-router would inject matched parameters
into request as *attributes*:

```php
$id = $request->getAttribute('id');
```

## Retrieving matched route name

When routing is successful, result will also contain a name of the route that
matched:

```php
$routeName = $result->getMatchedRouteName();
```

## URI generation

Because router have knowledge of the various paths it can match, it is
also typically used within applications to generate URIs to other application
resources, avoiding the need to hardcode them.

You can call the `assemble()` method with a route name and a list of parameters
and options to be used for URI assembling. Router will return intance of
PSR-7 `UriInterface`:

```php
$uri = $router->assemble('routename', ['id' => '123'], ['query' => ['p' => 2]]);
```

60 changes: 60 additions & 0 deletions docs/book/migration/v3-to-v4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Migrating from v3 to v4

zend-router v4 makes a number of significant changes that will affect your
application. This document details those changes, and provides suggestions on
how to update your application to work with v3.

## PSR-7 Rewrite

zend-router drops support for `Zend\Stdlib\RequestInterface` and switches to
[PSR-7 HTTP message interfaces](http://www.php-fig.org/psr/psr-7/)
`Psr\Http\Message\ServerRequestInterface`. That means that non-HTTP routing is
no longer supported.

## Backward incompatible changes

- `Zend\Router\Http\TreeRouteStack` was moved to `Zend\Router\TreeRouteStack`
- `RouteInterface::match()` method now accepts `Psr\Http\Message\ServerRequestInterface`
and always returns `Zend\Router\RouteResult`.
- `RouteInterface::assemble()` accepts same arguments as before, except for `'uri'` option, which
must be instance of `Psr\Http\Message\UriInterface` if present.
Returns instance of `Psr\Http\Message\UriInterface` or throws if route cannot
be assembled.
- `Zend\Route\RouteMatch` is removed and replaced with `Zend\Router\RouteResult`
- `RouteInterface::match()` method is no longer allowed to return partial match.
`Zend\Router\PartialRouteInterface` is introduced to provide that functionality.
`Chain`, `Hostname`, `Literal`, `Method`, `Regex`, `Scheme` and `Segment`
routes are now partial routes.
- `Chain` route now accepts partial routes only
- `Part` route now requires partial route for its base route.
- Base path support was dropped from the router. It is now responsibility of an
application and its url helpers.
- Router no longer provides absolute URI populated from current request. It is
now responsibility of application url helpers

## Http routes namespace change

In zend-router v3, HTTP specific routes were in `Zend\Router\Http` namespace.
With v4 zend-router became HTTP only router so the namespace was changed to
`Zend\Router\Route`.

If you were referring routes using their fully qualified class names in router
configuration you are urged to update your code. However, old FQCN are
registered as aliases in RoutePluginManager and configuration will continue
work unchanged.

## Wildcard route removal

`Zend\Router\Http\Wildcard` was deprecated starting in version 2.3.0. If you
were using it previously, it no longer exists. Wildcard route is considered
problematic, due to the fact that arbitrary route match parameters may be
specified, which could potentially lead to nefarious actions such as selection
of an alternate controller or controller action.


## Console routing

Console routing support was dropped from zend-router for version 4. If you use
zend-mvc-console, you will need to migrate to standalone console application
such as `zfcampus/zf-console` or `symfony/console`

124 changes: 46 additions & 78 deletions docs/book/routing.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,54 @@
# Routing

Routing is the act of matching a request to a given controller.

Typically, routing will examine the request URI, and attempt to match the URI
path segment against provided constraints. If the constraints match, a set of
"matches" are returned, one of which should be the controller name to execute.
Routing can utilize other portions of the request URI or environment as well.
For example, the host or scheme, query parameters, headers, request method, and
more.

The base unit of routing is a `Route`:

```php
namespace Zend\Router;

use Zend\Stdlib\RequestInterface as Request;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\UriInterface;

interface RouteInterface
{
public static function factory(array $options = []);
public function match(Request $request);
public function assemble(array $params = [], array $options = []);
public static function factory($options = []) : RouteInterface;
public function match(Request $request, int $pathOffset = 0, array $options = []) : RouteResult;
public function assemble(array $params = [], array $options = []) : UriInterface;
}
```

A `Route` accepts a `Request`, and determines if it matches. If so, it returns a
`RouteMatch` object:
A `Route` accepts a `Request`, and determines if it matches. It returns a
`RouteResult` object:

```php
namespace Zend\Router;

class RouteMatch
final class RouteResult
{
public function __construct(array $params);
public function setMatchedRouteName($name);
public function getMatchedRouteName();
public function setParam($name, $value);
public function getParams();
public function getParam($name, $default = null);
public function isSuccess() : bool;
public function isFailure() : bool;
public function isMethodFailure() : bool;
public function getMatchedRouteName() : ?string;
public function getMatchedParams() : array;
public function getAllowedMethods() : ?array;
}
```

Typically, when a `Route` matches, it will define one or more parameters. These
are passed into the `RouteMatch`, and objects may query the `RouteMatch` for
are passed into the `RouteResult`, and objects may query the `RouteResult` for
their values.

```php
$id = $routeMatch->getParam('id', false);
$id = $routeResult->getMatchedParams()['id'] ?? null;
if (! $id) {
throw new Exception('Required identifier is missing!');
}
$entity = $resource->get($id);
```

Typically, application will inject matched parameters into request as attributes.

```php
$id = $request->getAttribute('id');
if (! $id) {
throw new Exception('Required identifier is missing!');
}
Expand All @@ -62,10 +64,10 @@ namespace Zend\Router;

interface RouteStackInterface extends RouteInterface
{
public function addRoute($name, $route, $priority = null);
public function addRoutes(array $routes);
public function removeRoute($name);
public function setRoutes(array $routes);
public function addRoute($name, $route, $priority = null) : void;
public function addRoutes(array $routes) : void;
public function removeRoute($name) : void;
public function setRoutes(array $routes) : void;
}
```

Expand Down Expand Up @@ -125,30 +127,15 @@ adding it to the route stack.

### TreeRouteStack

`Zend\Router\TreeRouteStack` provides the ability to register trees of
routes, and uses a B-tree algorithm to match routes. As such, you register a
single route with many children.

A `TreeRouteStack` will consist of the following configuration:
`Zend\Router\TreeRouteStack` is similar to `SimpleRouteStack` but provides the
ability to register trees of routes.

- A base "route", which describes the base match needed, the root of the tree.
- An optional `route_plugins`, which is a configured
`Zend\Router\RoutePluginManager` that can lazy-load routes.
- The option `may_terminate`, which hints to the router that no other segments
will follow it.
- An optional `child_routes` array, which contains additional routes that stem
from the base "route" (i.e., build from it). Each child route can itself be a
`TreeRouteStack` if desired; in fact, the `Part` route works exactly this way.
Route name in `TreeRouteStack` route tree is identified by the individual route names
joined with `/` as a separarator so that it looks like `parent/child`.

When a route matches against a `TreeRouteStack`, the matched parameters from
When a route matches against a `TreeRouteStack`, merged matched parameters from
each segment of the tree will be returned.

A `TreeRouteStack` can be your sole route for your application, or describe
particular path segments of the application.

An example of a `TreeRouteStack` is provided in the documentation of the `Part`
route.

## HTTP Route Types

zend-router ships with the following HTTP route types.
Expand Down Expand Up @@ -179,7 +166,7 @@ $route = Hostname::factory([
```

In the above example, only a "subdomain" key will be returned in the
`RouteMatch`. If you wanted to also provide other information based on matching,
`RouteResult`. If you wanted to also provide other information based on matching,
or a default value to return for the subdomain, you need to also provide
defaults.

Expand All @@ -195,7 +182,7 @@ $route = Hostname::factory([
]);
```

When matched, the above will return two keys in the `RouteMatch`, "subdomain"
When matched, the above will return two keys in the `RouteResult`, "subdomain"
and "type".

### Zend\\Router\\Route\\Literal
Expand All @@ -215,7 +202,7 @@ $route = Literal::factory([
```

The above route would match a path "/foo", and return the key "action" in the
`RouteMatch`, with the value "foo".
`RouteResult`, with the value "foo".

### Zend\\Router\\Route\\Method

Expand All @@ -234,7 +221,7 @@ $route = Method::factory([
```

The above route would match an http "POST" or "PUT" request and return a
`RouteMatch` object containing a key "action" with a value of "form-submit".
`RouteResult` object containing a key "action" with a value of "form-submit".

### Zend\\Router\\Route\\Part

Expand Down Expand Up @@ -328,35 +315,16 @@ You may use any route type as a child route of a `Part` route.
> ### Route plugins
>
> In the above example, the `$routePlugins` is an instance of
> `Zend\Router\RoutePluginManager`, containing essentially the following
> configuration:
>
> ```php
> $routePlugins = new Zend\Router\RoutePluginManager();
> $plugins = [
> 'hostname' => 'Zend\Router\Route\Hostname',
> 'literal' => 'Zend\Router\Route\Literal',
> 'part' => 'Zend\Router\Route\Part',
> 'regex' => 'Zend\Router\Route\Regex',
> 'scheme' => 'Zend\Router\Route\Scheme',
> 'segment' => 'Zend\Router\Route\Segment',
> 'wildcard' => 'Zend\Router\Route\Wildcard',
> 'method' => 'Zend\Router\Route\Method',
> ];
> foreach ($plugins as $name => $class) {
> $routePlugins->setInvokableClass($name, $class);
> }
> ```
> `Zend\Router\RoutePluginManager`
>
> When using `Zend\Router\TreeRouteStack`, the `RoutePluginManager` is
> set up by default, and the developer does not need to worry about autoloading
> of standard HTTP routes.
> `RoutePluginManager` is already configured with default routes, and the
> developer does not need to worry about registering standard HTTP routes.
### Zend\\Router\\Route\\Regex

A `Regex` route utilizes a regular expression to match against the URI path. Any
valid regular expression is allowed; our recommendation is to use named captures
for any values you want to return in the `RouteMatch`.
for any values you want to return in the `RouteResult`.

Since regular expression routes are often complex, you must specify a "spec" or
specification to use when assembling URLs from regex routes. The spec is simply
Expand All @@ -365,7 +333,7 @@ the keys coming from either the captured values or named parameters passed to
the `assemble()` method.

Just like other routes, the `Regex` route can accept "defaults", parameters to
include in the `RouteMatch` when successfully matched.
include in the `RouteResult` when successfully matched.

```php
$route = Regex::factory([
Expand All @@ -380,7 +348,7 @@ $route = Regex::factory([
```

The above would match `/blog/001-some-blog_slug-here.html`, and return four
items in the `RouteMatch`, an "id", the "controller", the "action", and the
items in the `RouteResult`, an "id", the "controller", the "action", and the
"format". When assembling a URL from this route, the "id" and "format" values
would be used to fill the specification.

Expand All @@ -400,7 +368,7 @@ $route = Scheme::factory([
```

The above route would match the "https" scheme, and return the key "https" in
the `RouteMatch` with a boolean `true` value.
the `RouteResult` with a boolean `true` value.

### Zend\\Router\\Route\\Segment

Expand Down
4 changes: 3 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ docs_dir: docs/book
site_dir: docs/html
pages:
- index.md
- Introduction: intro.md
- Routing: routing.md
- Migration:
- "V2 to V3": migration/v2-to-v3.md
- "V3 to V4": migration/v3-to-v4.md
site_name: zend-router
site_description: 'zend-router: Flexible routing system for HTTP applications'
site_description: 'zend-router: Flexible routing system for PSR-7 HTTP applications'
repo_url: 'https://github.com/zendframework/zend-router'
copyright: 'Copyright (c) 2005-2017 <a href="http://www.zend.com/">Zend Technologies USA Inc.</a>'

0 comments on commit f6e49ca

Please sign in to comment.