In Laravel, a facade and a contract are two different ways to access a service container's underlying implementation.
Facade
A facade acts as a proxy for the underlying implementation and provides a simpler and more readable API for accessing it. For example, the Auth
facade in Laravel provides a convenient way to interact with the authentication system, without having to directly call the AuthManager
class.
Contract
On the other hand, a contract defines a set of methods that a class must implement, without specifying how those methods should be implemented. Contracts allow for greater flexibility and code reuse, as different classes can implement the same contract to provide similar functionality.
Difference between Facade and Contract
A facade is a static interface that provides access to the underlying implementation of a class, while a contract is an abstract interface that defines a set of methods that a class must implement.
For example, the Illuminate\Contracts\Auth\Authenticatable
contract defines the methods that a user model must implement in order to be authenticated by Laravel's authentication system. Any user model that implements this contract can be used with Laravel's built-in authentication features.
Here's an example of using the Auth
facade to authenticate a user:
use Illuminate\Support\Facades\Auth;
// ...
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication was successful
}
On the other hand, a contract is a way to define an interface for a service, without specifying its underlying implementation. Contracts define a set of methods that a service must implement in order to be considered valid. Contracts can be used to define a common API that can be implemented by different classes or services, allowing for greater flexibility and abstraction.
Here's an example of a contract definition for a user authentication service:
namespace App\Contracts;
interface Authenticatable
{
public function attempt(array $credentials): bool;
}
And here's an example of a class that implements the Authenticatable
contract:
namespace App\Services;
use App\Contracts\Authenticatable;
use Illuminate\Support\Facades\Auth;
class MyAuthService implements Authenticatable
{
public function attempt(array $credentials): bool
{
return Auth::attempt($credentials);
}
}
In this example, the MyAuthService
class implements the Authenticatable
contract, which defines a single method attempt()
. This method is then implemented by calling the attempt()
method on the Auth
facade, which provides the underlying implementation for user authentication.
Overall, facades and contracts provide different ways to interact with services in Laravel, with facades providing a more convenient syntax for accessing a service's implementation, and contracts providing a more flexible and abstract interface that can be implemented by multiple classes or services.
Usage of Facade and Contract
Suppose you want to send an email to a user after they register on your website. You can use the Mail
facade in Laravel to achieve this without having to create a new instance of the Mailer
class manually.
use Illuminate\Support\Facades\Mail;
// ...
Mail::to($user)->send(new WelcomeEmail($user));
In the above example, the Mail
facade is used to send an email to the user. The to()
method is used to specify the recipient of the email, and the send()
method is used to send the email using the WelcomeEmail
class.
Example usage of Contract:
Suppose you want to create a custom authentication service that uses a different implementation of the authentication logic than the default Auth
facade. You can create a new class that implements the Authenticatable
contract, and then bind it to the container using the contract.
// Define the contract
namespace App\Contracts;
interface Authenticatable
{
public function authenticate(array $credentials);
}
// Implement the contract
namespace App\Services;
use App\Contracts\Authenticatable;
class CustomAuthenticator implements Authenticatable
{
public function authenticate(array $credentials)
{
// Custom authentication logic goes here
}
}
// Bind the implementation to the container
$this->app->bind(Authenticatable::class, CustomAuthenticator::class);
In the above example, we have defined a new Authenticatable
contract that requires the implementation of the authenticate()
method. We then create a new CustomAuthenticator
class that implements the contract, and define the custom authentication logic in its authenticate()
method. Finally, we bind the implementation of the contract to the container using the bind()
method. Now, when the Authenticatable
contract is resolved from the container, it will return an instance of the CustomAuthenticator
class, which will provide the custom authentication logic.
So, in summary, facades provide a convenient way to access the underlying implementation of a service, while contracts provide a flexible way to define and implement a common API for multiple classes or services.