Imagine we’re going to develop for a situation like this:
We have chosen two providers that we will use for sending sms. Let these be SENDER1 and SENDER2. These two companies have given us API access so that we can send sms. Endpoints, user information, etc. of both APIs. is different. We will use one for sending SMS, but the necessary integration must be completed for both companies. Switching between the two should be easy.
Ok. Let’s start.
I used the following in the example project
- php v8.1.5
- laravel v9.11
First install new laravel application and serve it.
composer create-project laravel/laravel interface-example
php artisan serve
Let’s create an interface to app/Interfaces/SmsInterface.php
<?php
namespace App\Interfaces;
interface Sms
{
public function send(string $to, string $message): string;
}
Now let’s create our sender classes that implements this interface at app/Services/Sms directory.
Sender1.php
<?php
namespace App\Services\Sms;
use App\Interfaces\Sms;
class Sender1 implements Sms
{
public function send($to, $message): string
{
return 'Sms sent via Sender1.';
}
}
Sender2.php
<?php
namespace App\Services\Sms;
use App\Interfaces\Sms;
class Sender2 implements Sms
{
public function send($to, $message): string
{
return 'Sms sent via Sender2.';
}
}
Not we create SmsController with this command.
php artisan make:controller SmsController
After created controller update web.php route file.
<?php
use App\Http\Controllers\SmsController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/send-sms', SmsController::class);
Update the SmsController.php file like this.
<?php
namespace App\Http\Controllers;
use App\Interfaces\Sms;
class SmsController extends Controller
{
public function __invoke(Sms $sms)
{
return $sms->send('+123456789', 'Hello world!');
}
}
__invoke method mean is, this class including only one method and we can make this method work by defining the route file as above. It’s php feature.
In this controller, we stated that we will use the Sms Interface implementation. But which one? We have to show Laravel which one to use. If we don’t it will throw an error.
Now, let’s create SmsServiceProvier with this artinsa command.
php artisan make:provider SmsServiceProvider
Set the file as below.
<?php
namespace App\Providers;
use App\Interfaces\Sms;
use App\Services\Sms\Sender1;
use Illuminate\Support\ServiceProvider;
class SmsServiceProvider extends ServiceProvider
{
protected $defer = true;
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->app->bind(Sms::class, Sender1::class);
}
}
In the Register method, we have specified which class sms interface will use. We set the defer parameter as true. So we have it loaded only when needed.
Now, go to config/app.php file and add App\Providers\SmsServiceProvider::class to providers array. So, we notified to Laravel about the provider we created.
Now let’s visit to http://localhost:8000/send-sms link on browser.
Now if i want to changed sms sender from ‘Sender1’ to ‘Sender2’, just go to SmsServiceProvider and update the register method like this:
public function register()
{
$this->app->bind(Sms::class, Sender2::class);
}
Don’t forget to update use import command top on the page as follows.
use App\Services\Sms\Sender2;
And visit again to http://localhost:8000/send-sms link and we can see the sender has changed.