php - Laravel 存储库模型中的 API 调用

标签 php api laravel laravel-5 repository-pattern

我正在开发一个 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); 
    }    
}

我的问题

  1. 这是使用存储库模式进行 API 集成的正确方法吗?
  2. ValueFirst 存储库中是否发生与任何数据库事件相关的任何事情?例如:如果我想在 ValueFirst 的 API 响应后更新记录,我需要在存储库中执行此操作吗?
  3. 如果正确,有人可以向我展示模型交互是如何从存储库发生的吗?
  4. 现在,如果我需要在 ValueFirst 或任何其他供应商之间进行选择,该怎么做?我怎样才能从 Controller 做到这一点?

我将使用这个项目作为我的应用程序的框架

l5-Repository

请帮助我完成这个设计,我对 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/

相关文章:

php - 有没有办法在没有 imagemagick 或 Ghostscript 的情况下将 pdf 文件转换为 jpg?

php - 如何在 Virtuemart 中将 "product details"文本更改为我自己的文本?

api - 缓存 GET 调用的 RESTful API 结果的最佳方法

php - SQL 数据库中用户名的默认值

php - Laravel 附加枢轴数据没有错误

JavaBridge 不打开 php(无法连接到服务器)

php - PHPExcel中如何确定打印区域的最后一行?

php - 创建 PHP API : Checking from which server the API Request comes from

api - Docebo API 集成

laravel - 带有连接的 yajra DataTable 在 laravel 5 中不起作用?