我正在开发一个 Web 应用程序,我将在其中使用第三方 API 集成(支付网关、短信供应商、mailchimp 等电子邮件服务、其他外部 API)。我的应用程序将具有存储库模式,该模式将具有与我的每个模型关联的存储库,并且我的 Controller 将利用存储库功能。
现在我所有的 API 集成都在哪里?我应该将所有 API 集成保存在一个存储库中吗?
示例:
如果我有 SMS 提供商 Valuefirst,我的 Laravel 存储库设计是什么样的?
我的短信界面
interface ISmsProvider {
public function sendSms($mobileNo,$msg);
}
我的 ValueFirst(短信提供商)存储库
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
}
}
假设我有一个服务提供者类,我已经完成了接口(interface)和存储库的绑定(bind),我的 Controller 将如下所示
短信 Controller
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);
}
}
我的问题
- 这是使用存储库模式进行 API 集成的正确方法吗?
- ValueFirst 存储库中是否发生与任何数据库事件相关的任何事情?例如:如果我想在 ValueFirst 的 API 响应后更新记录,我需要在存储库中执行此操作吗?
- 如果正确,有人可以向我展示模型交互是如何从存储库发生的吗?
- 现在,如果我需要在 ValueFirst 或任何其他供应商之间进行选择,该怎么做?我怎样才能从 Controller 做到这一点?
我将使用这个项目作为我的应用程序的框架
请帮助我完成这个设计,我对 Laravel/存储库模式相当陌生。努力学习东西。 TIA:)
最佳答案
你的方法对我来说似乎很好,但有一些我需要改进的地方
首先,我将保留 ValueFirstRepository
类唯一负责管理 SMS API 的职责,并注入(inject)特定的存储库类 ( SmsRepository
) 来与数据库交互通过 eloquent (或者如果不需要存储库,则仅使用模型)
这里重要的一点是在一个类中保留管理 API 的责任,并在另一个类中保留与数据库交互的责任:
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
类中的事件,并响应该事件,实现一些监听器,这些监听器将执行与该消息相关的其他操作事件
另一种替代解决方案可能是直接在 Controller 中处理这些步骤:
短信 Controller
//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
的依赖将被注入(inject)到 Controller 中,而不是 ValueFirstRepository
类,并且 Controller 的方法会更大一些,但是已经完成了由您决定最适合您的方式
对于最后一个问题:如果您想更改供应商提供商,您可以使用 Laravel 的功能 bind interfaces to implementation通过 bind
方法:
App::bind( App\ISmsProvider::class , App\ValueFirstRepository::class );
这将告诉 laravel 在请求特定接口(interface)时注入(inject)哪个类。因此,在这种情况下,当请求 ISmsProvider
接口(interface)时,Laravel 将自动注入(inject) ValueFirstRepository
具体实例。
如果您想更改供应商,您只需将该行更改为:
App::bind( App\ISmsProvider::class , App\AnotherSMSVendorRepository::class );
并且将注入(inject) AnotherSMSVendorRepository
类,而不是 ValueFirstRepository
关于php - Laravel 存储库模型中的 API 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34102604/