Adventures in Engineering

Laravel resource and subdomain routes

Working on a side project this weekend I encountered an inconvenient default behaviour in Laravel's routing. Primarily, it just wasn't documented. Courtesy of this StackOverflow answer, I found the issue.

As a brief summary of my project config and its goals:

  • api.myapp.com and myapp.com can run from the same project
  • 'web' and ' api' groups are defined using subdomain routing (there's no path prefix for the API).
  • The API domain defined as api.{hostname}.{tld}
  • I'm using resource controllers/routes

When you do this, route('model.edit', ['id'=>1]) will error because the hostname and tld are required parameters.

To get around this error, I need to set default values for hostname and tld params, and there's no better way to do this than with a fairly simple middleware.

<?php

namespace App\Http\Middleware;

use \Illuminate\Http\Request;

class ApiHostname {
    public function handle (Request $request, $next) {
        // Set defaults for use with route() helpers.
        \URL::defaults([
            'domain' => $request->route()->parameter('domain'),
            'tld' => $request->route()->parameter('tld'),
        ]);

        // Remove these params so they aren't passed to controllers.
        $request->route()->forgetParameter('domain');
        $request->route()->forgetParameter('tld');

        return $next($request);
    }
}

I then configure this middleware to run for both web and api groups in my RouteServiceProvider.php

And there you have it! API subdomain routing, resource controllers and route helpers all in one, fell, swoop!

Happy coding!

developerjack