Routing

Introduction

All requests to your application are handled by Laravel unless you create the routes using one of the specific methods described below.

Defining Routes

The Streams platform has a couple of ways it routes requests, which are listed below. Otherwise, standard Laravel routing applies.

Route Files

You can configure routes just as you would in a regular Laravel application using the routes/web.php file.

Service Providers

You may use the enhanced service providers that come with the Streams platform to define routes.

Streams Router

The Streams platform provides a Route::streams() method for defining routes. All streams-specific routing approaches pass through this method.

// Options
Route::streams('uri', [
    'foo' => 'bar',
]);

// View
Route::streams('uri', 'view');

// Controller
Route::streams('uri', 'App\Http\Controller\[email protected]');

The first argument is the URI and the second is either:

Stream Routes

Defining routes in your stream configuration makes it easy to automate naming and URL generation around your domain information and entities.

Define stream routes using a action => options format, where options is again either the URI, controller and method string, or an array of route options.

// streams/contacts.json
{
    "routes": {
        "index": "contacts",
        "view": "contacts/{id}",
    },
    "profile": {
        "uri": "contacts/{id}",
        "view": "profile"
        }
    }
}

Automatic Naming

Unless a route name is specified, stream configured routes automatically name themselves like streams::{stream}.{action}.

$url = route('streams::contacts.index');

Automatically Resolved Views

Unless a view is specified, the associated requests will attempt to resolve a view automatically.

// streams/contacts.json
{
    "routes": {
        "index": "contacts",    // resources/contacts/index.php
        "view": "contacts/{id}", // resources/contacts/view.php
        "rss": "contacts/{id}/rss" // resources/contacts/rss.php
    }
}

You can configure automatic view patterns within the streams/route.php configuration file. The process ignores the views if they do not exist.

Parameters

The Streams platform adds support for deep parameter variables using a dot notation when using the URL::streams() method to generate URLs.

Route::streams('uri/{foo.bar}', 'view');

Stream Parameter

You can specify the stream associated with the route using the route option or by using the {stream} URI segment variable in your URI pattern to resolve the stream by its handle.

Route::streams('address-book/{stream}', 'contacts');

Consider locking down this routing pattern using a parameter constraint.

Route::streams('address-book/{stream}', [
    'view' => 'contacts.list',
    'constraints' => [
        'stream' =>  '(businesses|family)'
    ],
]);

The resolved stream will be available within the view:

<h1>{{ $stream->name }}</h1>

<ul>
    @foreach ($stream->entries()->get() as $entry)
    <li>{{ $entry->name }}</li>
    @endforeach
</ul>

Entry Parameters

You can specify a stream entry associated with the route using the route option or by using the {id} URI segment variable in your URI pattern to resolve the entry by its ID or handle.

Route::streams('address-book/{stream}/{id}', 'contacts');

You can also use {entry.*} parameters to query the entry by its field values.

// address-book/contacts/[email protected]
Route::streams('address-book/{stream}/{entry.email}', 'contacts');

The first matching entry will be available within the view:

<h1>{{ $entry->name }}</h1>

A 404 error page will be displayed entry resolution is attempted, but no entry is found.

Route Options

All Streams platform-specific methods of registering routes support the following route options.

All route options are parsed with controller data:

Route::streams('address-book/{stream}/{id}', [
    'view' => '{streams.handle}',
]);

Views

Use the view option to specify a view to render:

Route::streams('uri', [
    'foo' => 'bar',
    'view' => 'example',
]);

Streams

Use the stream option to specify the stream associated with the request. Stream configured routes will do this automatically.

Route::streams('uri', [
    'stream' => 'contacts',
]);

The stream is automatically injected into the view:

<h1>{{ $stream->name }}</h1>

<ul>
    @foreach ($stream->entries()->get() as $entry)
    <li>{{ $entry->name }}</li>
    @endforeach
</ul>

Entries

You can also specify a specific entry:

Route::streams('uri/{id}', [
    'stream' => 'contacts',
]);

The stream entry is automatically injected into the view:

// uri/ryan_thompson
<h1>{{ $entry->name }}</h1>

You can use entry fields to query entries for the view.

// uri/[email protected]
Route::streams('uri/{entry.email}', [
    'stream' => 'contacts',
]);

You can also hard code the entry ID or handle:

Route::streams('uri', [
    'stream' => 'contacts',
    'entry' => 'ryan_thompson',
]);

The first result is automatically injected into the view:

// uri/ryan_thompson
<h1>{{ $entry->name }}</h1>

Redirects

Use the redirect and optional status_code option to specify a redirect:

Route::streams('uri/{entry.name}', [
    'redirect' => '/new/uri',
    'status_code' => 301, // Default
]);

Redirects highlight a good use case to leverage the fact that route options are parsed with controller data:

Route::streams('uri/{entry.name}', [
    'redirect' => '/new/uri/{stream.handle}/{entry.name}',
    'status_code' => 301, // Default
]);

Native Redirects

You can create Laravel redirects in your routes/web.php using the Route facade as well:

Route::redirect('/from', '/to');
Route::redirect('/from', '/to', 301);
Route::permanentRedirect('/from', '/to');

Named Routes

Use the as option to specify the name of the route:

Route::streams('uri', [
    'view' => 'example',
    'as' => 'login',
]);

You can refer to the route by name using the typical Laravel methods:

$url = route('login');

HTTP Verbs

Use the verb option to specify the HTTP verb the route should respond to:

Route::streams('uri', ['verb' => 'any']);
Route::streams('uri', ['verb' => 'get']); // Default
Route::streams('uri', ['verb' => 'put']);
Route::streams('uri', ['verb' => 'post']);
Route::streams('uri', ['verb' => 'patch']);
Route::streams('uri', ['verb' => 'delete']);
Route::streams('uri', ['verb' => 'options']);

Route Middleware

Use the middleware option to assign additional middleware to the route:

Route::streams('uri', [
    'middleware' => ['first', 'second']
]);

Parameter Constraints

Use the constraints option to specify allowed parameter formatting for the route using regular expression:

Route::streams('uri/{name}', [
    'constraints' => ['name' => '[A-Za-z]+']
]);

Laravel does not support dots in parameter names at this time. For this reason, {entry.name} type parameters transform into {entry__name}.

Route::streams('uri/{entry.name}', [
    'constraints' => ['entry__name' => '[A-Za-z]+']
]);

Disabling CSRF

You can disable CSRF protection using the csrf option.

Route::streams('uri', [
    'csrf' => false
]);

Deferring Routes

Use the defer option to defer registering a route.

Route::streams('/{id}', [
    // ...
    'defer' => true,
]);

Generating URLs

You may use the URL::streams() method to generate URLs for named routes, including those with dotted parameter variables. This method also supports parsing URL strings with parameter data. The extra data argument is appending as a query string. Use the absolute argument to control whether the resulting URL is absolute or not.

URL::streams($target, $parameters = [], $extra = [], $absolute = true);

$entry = Streams::entries('contacts')->first();

// contacts/{entry.email}/{entry.id}
$url = URL::streams('streams::contacts.view', ['entry' => $entry]);

// contacts/{email}/{id}
$url = URL::streams('streams::contacts.view', $entry);

You can also use Laravel URL generation for named routes, though dotted parameters are not supported using Laravel methods:

// Generating URLs.
$url = route('streams::contacts.index');

// Generating Redirects.
return redirect()->route('streams::contacts.index');

Error Pages

Errors render views based on the status code of the error. For example, a 404 error will look a view in resources/views/errors/{status_code}.blade.php.

Laravel will automatically render a 404 page for any unhandled routes.