Laravel Queues in Action (2nd edition) is now available!

Handling HTTP Requests in Laravel

Updated: Jan 11, 2019 — 2 min Read

You probably know this already, but for those of you who don't get it yet, a web server's job is pretty simple; it listens to requests, runs a program, and then sends the output of that program as a response. If you look deeper into this simple task you can find many complicated stuff but that's not what we're here to discuss.

You point your client (a browser for example) to google.com and the program on the server looks at the given request and prepares a proper response for you:

return searchResultsForTerm($_GET['search_term']);

This looks simple, no matter how complicated a program is the end result is a response that's sent to the client. Let's look at the program called Laravel that your server is running:

$app = new Illuminate\Foundation\Application(
    dirname(__DIR__)
);

// Bind Important Interfaces To The Container

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);

In this program an Application instance is created which we use to create an instance of Kernel; the request is captured from the server then the Kernel handles it and prepares a response. Just before the program finishes, the response is sent to the client, and finally the kernel terminates and the script exits.

Every magical thing that you love about laravel happens inside $kernel->handle().

The Service Container

Laravel has a powerful service container that manages the application's classes' dependencies. It learns how an instance of a class can be created and each time you want an instance you can just get it from the container.

In the code above $app holds an instance of that container, and after we acquire that instance Laravel registers the Kernel binding along with some other bindings:

$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

So later in the script when we ask for Illuminate\Contracts\Http\Kernel, the containers gives us an instance of App\Http\Kernel.

We're not going to look into the container in this dive, but the container is used a lot in the Laravel core so I thought you should be familiar with what it does.

Back to the Kernel

The handle() method of the Http\Kernel sends your request through the router and handles any exceptions that might rise. However, before sending to the router we need to prepare the application, calling the bootstrap() method will run the code needed for that. Here's the list of bootstrappers:

protected $bootstrappers = [
    \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
    \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
    \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
    \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
    \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
    \Illuminate\Foundation\Bootstrap\BootProviders::class,
];
You can find more information on how exceptions are handled in Laravel by checking this dive.

The sendRequestThroughRouter() method called from handle() has the following code:

return (new Pipeline($this->app))
    ->send($request)
    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
    ->then($this->dispatchToRouter());

This translates to the following:

Send the request to the list of global middleware if needed, and then take the result and dispatch it to the router.

The router will find the suitable route that matches the request, collects the list of middleware assigned to this route and sends the request through them, run the code in your route definition, and finally prepares the response for display.

Terminating The Kernel

Once the response is ready, it's sent to the client via $response->send(), after that the Http\Kernel does some housekeeping before it terminates. This house keeping includes running Terminable Middleware and any termination callbacks registered in the container.


If you have any questions or find parts that need more clarification, please let me know. I'm going to update the post with more information based on the feedback I receive.

Hey! 👋 If you find this content useful, consider sponsoring me on GitHub.

You can also follow me on Twitter, I regularly post about all things Laravel including my latest video tutorials and blog posts.

By Mohamed Said

Hello! I'm a former Laravel core team member & VP of Engineering at Foodics. In this publication, I share everything I know about Laravel's core, packages, and tools.

You can find me on Twitter and Github.

This site was built using Wink. Follow the RSS Feed.