Laravel Aliases and Contracts

laravel alisases and contracts

Interfaces are a huge part of the Laravel framework. You can also call them contracts, this is how they are referred to on Github. This is the collection of interfaces that the Laravel framework itself makes use of. By browsing the contracts repository at Github, you can become familiar with the entire API of the framework. All of the concrete classes of the framework implement these various interfaces. In fact, when getting to know a software project, it is not a bad idea to start by browsing all of the interfaces. This tells you what methods will be available to you.


Cache Repository

As an example, we can take a look at the Cache repository.

By taking a look at this interface, we can see that any concrete implementation will need to abide by the methods defined in the contract. We can see this would be things like has(), get(), pull(), put(), add(), increment(), decrement(), forever(), remember(), sear(), rememberForever(), and forget(). As we look at this, we can see this makes for great documentation. Need to know what methods are available to you in a class? Just look at the interface it implements. Laravel’s contracts component is a collection of interfaces for all of the various APIs that the Framework makes available to users.


Pre Configured Interface Bindings

Any concrete class can implement any interface it likes as long as it adheres to the contract. So how do we know what implementation we will get when we ask for a specific interface? If you make use of Laravel, of course you are going to want to make use of the functionality of the framework, not just it’s interfaces. We can find the mapping in registerCoreContainerAliases()

It is in this method where all of the default aliases and their mappings are declared. All of this comes back to the concept of putting classes into the container and resolving objects out of the service container, also known as the IoC container. It is because of the service container and alias mapping that you can do things such as the following, that in effect are all the same exact thing.

Now, this is an example of the behavior we get for the built in routing class of Laravel. In addition to all this flexibility and syntactic sugar, the other huge benefit of all these contracts is that you can very easily swap out the default implementation with something else. Personally, I have had no reason so far to ever need to do this. If you have a situation where a particular requirement of a project demands that a particular class or implementation of a component be used, then you are not out of luck. You can still use Laravel, you just need to register your own component or class into the service container. Then, when you ask for that interface in your code, you will be given the correct implementation. Here is where you can learn more about the Laravel Service Container. Let’s examine a little bit more about how this works.


Register With The Service Container (Put classes into the container)

You will often hear the phrase, “register to the service container”, or “bind into the service container”. When I hear this, I simply think “Make classes available to the application by way of the service container”. Think of the service container as a two way operation. We register, or put classes into, the service container, and then later on we can resolve, or take out of the service container, an object, or instance of any registered classes that we might like to make use of. This usually happens with the register() method of a service provider. For example, here is that very registration for the Cache component of Laravel.

We can see that it is the singleton() method which does the work for us. This is mostly the same as if you were to call the bind() method. The difference between the two is that the singleton pattern is going to give the developer a shared instance of the object at all times. A new object is not created every time. Now in the snippet above, there are a few options for various keys. Those are cache, cache.store, and memcached.connector. Which one gets resolved depends on the configuration of the application. When a request is made of one of those keys, it is the closure that will return an instance of the given class.

Here is that singleton() method which is part of the Container class.

This method actually makes use of the bind() method, but it sets the third parameter to true, which indicates that this is a shared instance. Here is that bind() method.

Read the comments to understand how it all works.


Resolve Out of The Service Container (Get Objects out of the container)

Resolving objects out of the service container simply means that when you go to use a component or object in your application code, it is the service container that handles building up any dependencies and requirements needed to simply hand over an object that is ready to do it’s work. It’s a convenience for the developer, and mostly happens with out you even realizing it.

Consider the app() helper function, which calls a make() method on the application class.

Here is that make() method it defers to.

Again, the comments help us understand what is happening. Ultimately the work is being done by the make() method of the Container, which is the Application parent. Here is that make() method.

We can see that after all the logic of this method happens, finally we are returned an Object. It is this object which is an instance of whatever you asked for in your application code. In other words, depending on the key you asked for, you get the desired (Object | Service | Component) back.

One thing to note in the make() method of the Application class, is that it makes use of a getAlias() method. This is how you are able to pass the key, alias, class, or contract, to the app() method, and the framework knows how to resolve everything correctly. Here is that very method.

We can see it makes use of a convenient ternary operator to check if there is already an alias registered, and if so just return it. If not, we return the value of the $abstract variable which is most likely the key. This is how the contract or interface would be normalized into a standard alias key. In other words, if you pass something like Illuminate\Contracts\Routing\Registrar the software can translate this to the key of router.


Laravel Aliases and Contracts Summary

In this tutorial, we took a closer look at the aliases and contracts component of Laravel. We found that the interfaces themselves act as great documentation to help a developer explore the api that is exposed by any given class of the framework. We also dug into how when instantiating objects via the service container, there is a lot of flexibility in how to go about doing that. By looking closely at how all of this works, we can see how the Container and Application classes are really the meat and potatoes of Laravel. We register classes into the service container, and fetch objects out of it as needed. This is a key foundation of how Laravel works.