So I’ve been talking a lot about different components Symfony offers. In case you’re not familiar with the component term in the Symfony ecosystem, you just have to know that components are standalone libraries you can install in your project, without having your project to be entirely written with Symfony. You can simply add one Symfony component in your project if a feature interests you. The Symfony framework uses all of these different components to give you a pleasant developer experience.
Among those dozens of components, 3 are an absolute focus on HTTP. Given their name (HttpFoundation, HttpKernel and HttpClient), it may be confusing if you’re new to the Symfony ecosystem. Each of them solves specific needs. Because we could wonder: why don’t the Symfony core team put all HTTP stuff in one and only one “Http” component? Let’s see how using this trio could definitely change the way you deal with HTTP in your applications and projects.
Foundation, Kernel and Client
The HttpFoundation component defines an object-oriented layer to manipulate what makes the foundations of HTTP (which isn’t a big surprise). But what do I mean when talking about foundations of HTTP?
You surely know that HTTP is based on on a Request-Response schema. A client sends a request to a server, then the server returns a response. This component defines classes and interfaces to manipulates those requests and responses the object-oriented way. Instead of having to deal with PHP superglobals like
$_COOKIE and so on, you’ll be able to use classes like
Request and do the same thing.
These classes comes with handy methods and helpers to retrieve information from the request, manipulate cache rules, etc. Moreover, you can easily create streamed responses as well as JSON responses (with headers automatically set) for instance. The component also comes with an util to anonymize IP addresses.
What’s actually cool is these foundations are used in many places of the framework (as we will see in just a moment), so you always manipulate the same type of objects. You may now better understand why this component is called HttpFoundation. It is somehow the base of other HTTP-based components of Symfony.
In short: the HttpFoundation component roughly defines a model that can be used for all HTTP stuff across other Symfony components and bundles. It provides a solid and common base.
HTTP Kernel is where the magic happens. It uses the model we just saw to handle the request and return a response. Simple as that. The complexity of the internal request processing can be super small or contains a million lines of code, the primary goal of the kernel is pretty basic.
When using the Symfony framework and writing an application with it, the kernel is created, booted and used by the front-controller.
Wait, what is the front-controller? It’s the entrypoint of your application. All requests going through your application are going through these lines of code before being processed in the different controllers. Here is how it could look like if you use the HttpKernel standalone component in your application:
On a side note, if you’re creating a Symfony application, the front-controller won’t look like this since version 5.3 and the addition of the Runtime component.
The request is created from PHP globals thanks to the handy
createFromGlobals method of HttpFoundation component. The request is handled by the kernel, a response is created and sent. You can already see that Kernel and Foundation are tightly linked.
The kernel makes great use of events and the EventDispatcher component. Indeed, the kernel will emit different event types at precise moments of the request processing.
This means you can plug yourself to these events to add logic at key moments, synchronously while the request is being processed by the Kernel. Here is the complete list of these moments:
- A request arrives ;
- The controller containing the route to process the request has been found ;
- The arguments of the controller have been resolved (extracting data from the URL, services injection, etc.) ;
- The controller didn’t return a Response instance (from HttpFoundation’s model!) and further processing is necessary to complete the response ;
- Just before the response is considered fully generated, if you need to modify it at last moment ;
- The response is completely generated ;
- The response is sent back to the client ;
- An uncaught exception is thrown during request processing.
The HttpKernel is flexible enough to adapt to all your needs. Using these events is an amazing tool for decoupling and amazing for code maintainability. It allows you to split responsibilities. It provides a way to add a huge amount of logic without bringing an absolute mess in your code architecture. Each task can be attached to an event listener plugged on any of these events. To go further, you can find more details and a workflow of the request directly on the Symfony documentation.
We now have a model, and a kernel that uses this model to process a request to a valid response. The chain is now complete. So what is this so-called HttpClient component?
HttpClient offers a ready-to-use headless “browser”, or more accurately, client. Headless is a term used to designate a browser that doesn’t have an user interface (UI). You probably already used a headless client if you’re into PHP and dealing with APIs, with cURL (which must be the most famous one).
The HttpClient component is a layer on top of cURL that allows you to make and send requests programmatically. The difference with cURL is it uses a object-oriented approach, instead of the classical functional approach. Indeed, you’ll use the model of the HttpFoundation component to create your request and parse responses.
You can easily configure one HTTP client by service you’re querying. Super useful if you have specific configuration for each service, like cache control, authentication and so on.
If you don’t know about the HttpClient component, definitely take a look at the documentation to ensure you’ll understand the full power of it.
Symfony loves HTTP and shows it well! Even if Symfony is a big framework that’s bundled with hundreds and thousands of features that have nothing to do with HTTP, it remains a web framework in any case.
Using one of these three components, or even all of them can truly improve the way your application works by providing solid models and mechanisms.
I hope you can see clearer now between those different components focused on this protocol. Did you know that, at the time of writing (December 2021), these three components are cumulating more than 600,000,000 total downloads together?