This article is part of a series. The first part is explaining the details of the app we're building, please read it before going further. As a reminder, this is the 3 parts of the apps and the domain we use locally to access them.
App part | Domain |
---|---|
Marketing site | eventlist.test |
Public API | api.eventlist.test |
User sites | parisrockshows.test,... |
Starting point
So we have our 3 main parts of the apps: marketing webite, public API, and User sites. All have different domains, and user sites can have any domains.
1<?php
2
3/*
4|--------------------------------------------------------------------------
5| Web Routes
6|--------------------------------------------------------------------------
7|
8| Here is where you can register web routes for your application. These
9| routes are loaded by the RouteServiceProvider within a group which
10| contains the "web" middleware group. Now create something great!
11|
12*/
13
14use App\Event;
15
16
17// Marketing website hosted on eventlist.com
18
19Route::get('/', 'MarketingController@home');
20Route::get('/features', 'MarketingController@features');
21Route::get('/pricing', 'MarketingController@pricing');
22
23
24// API endpoints all accessible via api.eventlist.com
25// Auth user via default Laravel auth
26
27Route::get('/', function () { return ['up' => true]; });
28Route::get('/event/{id}', function ($id) {
29 return Event::find($id);
30});
31
32// USER GENERATED Sites
33// parisrockshows.com, concerts-madrid.com
34
35Route::get('/', 'Tenant\EventController@home');
36Route::get('/events', 'Tenant\EventController@index');
37Route::get('/event/{event}', 'Tenant\EventController@show');
Routing for known domains
In this app, we know the marketing website and api domains. We can setup this part with the domain
method.
We're introduce two new configuration keys here. Make sure marketing_domain
and api_domain
are added to your config/app.php
file. The point is to be able to handle domains for local development environment.
1// Marketing website hosted on eventlist.com
2Route::domain(config('app.marketing_domain'))->group(function () {
3
4 Route::get('/', 'MarketingController@home');
5 Route::get('/features', 'MarketingController@features');
6 Route::get('/pricing', 'MarketingController@pricing');
7
8});
9
10
11// API endpoints all accessible via api.eventlist.com
12// Auth user via default Laravel auth
13
14Route::domain(config('app.api_domain'))->group(function () {
15
16 Route::get('/', function () { return ['up' => true]; });
17 Route::get('/event/{id}', function ($id) {
18 return Event::find($id);
19 });
20
21});
In config/app.php
, you would typically add:
1return [
2 // ...
3
4 'marketing_domain' => env('MARKETING_DOMAIN', 'eventlist.com',
5 'api_domain => env('API_DOMAIN', 'api.eventlist.com',
6
7 // ...
8];
Handling custom user domains
Those domains are dynamics: they exists in your database, so you don't know them when you are setting up your routes. The domain is a variable here, just like {id}
in the API route.
In Laravel official docs you'll only find the subdomain use case but it can be adapted to work with domains.
1// USER GENERATED Sites
2// concerts-paris.com, concerts-madrid.com
3
4Route::domain('{user_domain}')->group(function() {
5
6 Route::get('/', 'Tenant\EventController@home');
7 Route::get('/events', 'Tenant\EventController@index');
8 Route::get('/event/{event}', 'Tenant\EventController@show');
9
10});
If you try to access you site via parisrockshows.test
, you'll get a 404. I believe this feature was really built with subdomains in mind. Laravel is not able to match the user_domain
to a full domain name (with extension or even subdomains).
In the RouteServiceProvider, we'll access the Router from the container, and explicitely pass the Router a regex to match the {user_domain} variable.
1// In src/Providers/RouteServiceProvider.php
2
3public function boot()
4{
5 $this->app['router']->pattern('user_domain', '.*');
6
7 parent::boot();
8}
TO BE CONTINUED...