【问题标题】:API Calls in Laravel Repository ModelLaravel 存储库模型中的 API 调用
【发布时间】:2016-03-10 05:28:08
【问题描述】:

我正在开发一个 Web 应用程序,我将在其中使用第三方 API 集成(支付网关、SMS 供应商、mailchimp 等电子邮件服务、其他外部 API)。我的应用程序将具有存储库模式,该存储库模式将具有与我的每个模型关联的存储库,并且我的控制器将使用存储库功能。

现在我的所有 API 集成都来自哪里?我应该将所有 API 集成保存在一个存储库中吗?

例子:

如果我有一个 SMS 提供商 Valuefirst,我的 Laravel 存储库设计是什么样的?

我的短信界面

interface ISmsProvider {
    public function sendSms($mobileNo,$msg);
}

我的 ValueFirst(SMS 提供者)存储库

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); 
    }    
}

我的问题

  1. 这是使用存储库模式进行 API 集成的正确方法吗?
  2. ValueFirst 存储库中是否发生了与任何数据库活动相关的任何事情?例如:如果我想在 ValueFirst 的 API 响应后更新记录,我是否在存储库中进行?
  3. 如果正确的话,谁能告诉我模型交互是如何从存储库中发生的?
  4. 现在,如果我需要在 ValueFirst 或任何其他供应商之间进行选择,该怎么办?如何从控制器执行此操作?

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

l5-Repository

请帮助我完成这个设计,我对 Laravel / 存储库模式相当陌生。努力学习东西。 TIA :)

【问题讨论】:

    标签: php api laravel laravel-5 repository-pattern


    【解决方案1】:

    你的方法对我来说似乎不错,但我需要改进

    首先,我将保留 ValueFirstRepository 类以管理您的 SMS API 的唯一职责,并注入一个特定的存储库类 (SmsRepository) 以通过 eloquent 与 DB 进行交互(如果您不这样做,则只有一个模型'不需要存储库)

    这里的重点是在一个类中保持管理 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 在请求特定接口时注入的类。所以,在这种情况下,当请求一个ISmsProvider 接口时,Laravel 会自动注入一个ValueFirstRepository 具体实例。

    如果您想更改供应商,您只需将行更改为:

    App::bind( App\ISmsProvider::class , App\AnotherSMSVendorRepository::class ); 
    

    并且AnotherSMSVendorRepository 类将被注入而不是ValueFirstRepository

    【讨论】:

    • 感谢您的详细解释。另外我想知道在这个流程之间服务在哪里出现?除了存储库,服务在哪里出现的接口。你能告诉我上面例子中的一个用例吗?
    • @user34305 :使用ValueFirstRepository 类:我们可以将其命名为“服务”而不是“存储库”,因为它是用于与 SMS API 交互的服务类。 “存储库”这个词更多地用于表示数据库之上的抽象层。事实上,进行App::bind 调用的好地方是为短信服务类提供绑定的服务提供者
    • 一个服务也可以是一个 Laravel 内部服务类:一个用于处理数据库连接的类,一个用于 Logger 的类等等。几乎任何你通过Service Provider注册的类
    • 它们是两个不同的概念:存储库是您使用类在数据库(在我们的例子中是 sms 数据库实体)上创建抽象层的设计,服务是一个广义术语,并且它包括您应用程序的几乎任何类型的服务类。如果你想在 Laravel 中找到更多关于服务和存储库的谷歌示例并检查它们的使用方式
    • 感谢 Moppo 回答所有问题
    猜你喜欢
    • 2014-08-13
    • 2018-08-21
    • 2018-08-27
    • 2014-03-15
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    相关资源
    最近更新 更多