我正在开发一个Web应用程序,我将使用第三方API集成(支付网关,SMS供应商,电子邮件服务,如mailchimp,其他外部API)。我的应用程序将具有存储库模式,该模式将具有与我的每个模型相关联的存储库,并且我的控制器将使用存储库功能。
现在我的所有API集成在哪里?我应该将所有API集成保存在单个存储库中吗?
示例:
如果我有一个SMS提供商Valuefirst,我的laravel存储库设计如何?
interface ISmsProvider {
public function sendSms($mobileNo,$msg);
}
class ValueFirstRepository implements ISmsProvider {
public function sendSMS($mobieNo,$msg)
{
//API Call to ValueFirst SMS provider
// Any database insertions/updates to SMS model
// Any file logs
}
}
假设我有一个服务提供者类,我已经完成了接口和存储库的绑定,我的控制器看起来像
class SmsController extends BaseController {
// ISmsProvider is the interface
public function __construct(ISmsProvider $sms)
{
$this->sms = $sms;
}
public function sendSMS()
{
$mobileNo = '9999999999';
$msg = 'Hello World!';
$users = $this->sms->sendSMS($mobileNo,$msg);
}
}
我的问题
我将把这个项目用作我的应用程序的skelton
请帮我这个设计,我对laravel / repository模式相当新。试着学习东西。 TIA:)
答案 0 :(得分:3)
你的方法对我来说似乎很好,但有一点我会改进
首先,我会保持ValueFirstRepository
类具有管理SMS API的唯一负责任,并注入特定的存储库类(SmsRepository
)以通过雄辩(或只是一个)与数据库进行交互模型,如果你不需要存储库)
这里重点是保持在一个类中管理API的负责任性以及在另一个类中与DB交互的责任:
<强> ValueFirstRepository 强>
class ValueFirstRepository implements ISmsProvider
{
//INJECT REPOSITORY CLASS TO INTERACT WITH DB
public function __construct(SmsRepository $smsRepo )
{
$this->smsRepo = $smsRepo;
}
//this method will be called from your controller
public function sendSMS($mobieNo,$msg)
{
//API CALL
$info = this->sendSMSAPI($mobieNo,$msg);
//DB CALL
$this->smsRepo->save( $info );
// Any file logs
}
//this will actually interact with the API
protected function sendSMSAPI($mobieNo,$msg)
{
//API Call to ValueFirst SMS provider
}
}
此解决方案的一个小型变体可能是在发送短信时使用事件和在ValueFirstRepository
类中触发事件,并响应该事件实现一些将执行与事件相关的其他操作的侦听器
另一种替代解决方案可能是直接在控制器中处理这些步骤:
短信控制器
//INJECT THE DEPENDECIES IN YOUR CONTROLLER
public function __construct(ISmsProvider $sms, SmsRepository $smsRepo )
{
$this->sms = $sms;
$this->smsRepo = $smsRepo;
}
public function sendSMS()
{
//send SMS
$mobileNo = '9999999999';
$msg = 'Hello World!';
$info= $this->sms->sendSMS($mobileNo,$msg);
//use the model to save data
this->$smsRepo->save($info);
}
这次SmsRepository
的依赖关系会被注入到控制器中,而不是ValueFirstRepository
类,而控制器的方法会变得更大,但是由你来决定最好的你的方式
关于最后一个问题:如果您想更改供应商提供商,可以通过bind
方法使用Laravel的功能bind interfaces to implementation:
App::bind( App\ISmsProvider::class , App\ValueFirstRepository::class );
这将告诉laravel wich类在请求特定接口时注入。因此,在这种情况下,当请求ISmsProvider
接口时,Laravel将自动注入ValueFirstRepository
具体实例。
如果您想更改供应商,则只应将该行更改为:
App::bind( App\ISmsProvider::class , App\AnotherSMSVendorRepository::class );
将注入AnotherSMSVendorRepository
类而不是ValueFirstRepository