Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Poindexter's avatar

Multi external API (make DRY?)

Hi guys, I am breaking my head around the following: In my app users have the option to connect their woocommerce site.

Process:

  1. Users enters their url in form and submit form
  2. My WoocommerceAuth service class generates an auth url and redirect the user to it
  3. User allows access trough the auth url and returns back to my app
  4. The external api sends a response to the callback of my app, here I will save the users consumer_key and consumer_secret to my database (WooAccount table/model).
  5. Whenever a new WooAccount is created, I will dispatch a job for each part like SyncOrders, SyncProducts. // This all works fine

Within each job I am doing this right now:

public function __construct($wooAccount)
{
    $this->wooAccount = $wooAccount;
    $woocommerce = new Client(
        $wooAccount->store->url,
        $wooAccount->consumer_key,
        $wooAccount->consumer_secret,
        [
            'wp_api'     => true,
            'version' => 'wc/v3',
            'verify_ssl' => false
        ]
    );
    $this->woocommerce = $woocommerce;
}

It works, but it is not quite DRY.. How could I improve this and easy instantiate a new api client connection each time without repeating myself? All the external api tutorials/github packages I checked are using a service provider. All these only use 1 api connection set by the app owner and not by the user himself.

I was thinking about doing something like this on my WooAccount model:

public function wooApi()
{
    return new Client($this->store_id, $this->consumerKey, $this->consumer_secret, [
            'wp_api'     => true,
            'version' => 'wc/v3',
            'verify_ssl' => false
        ]
);
}

Would love to get some feedback and help pointing me to the right direction.

0 likes
8 replies
Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Use service providers

https://laravel.com/docs/6.x/container#binding-basics

(only added store_id and I cannot recall if you have to add the parameters after $app in the function, or $this works as well. Should be easy to test though)

$this->app->bind('WooClient', function ($app, $params) {
    return new Client($params['store_id'], $params['consumerKey'], $params['consumer_secret'], [
            'wp_api'     => true,
            'version' => 'wc/v3',
            'verify_ssl' => false
        ]
);
});

And resolve

$this->app->makeWith('WooClient', ['store_id' => 1]);
Poindexter's avatar

Another question about this; is it good practice to create something like this in my WooAccount model:

public function getWooClient()
{
    return app()->makeWith('WooClient', ['store_id' => $this->store_id,'consumer_key' => $this->consumer_key, 'consumer_secret' => $this->consumer_key]);
}

So I can just grab the current client connection within a job for a specific model instance by doing

$wooAccount->getWooClient();
Sinnbeck's avatar

I see no problem with doing that. :) but consider doing this to ensure you don't load it more than once

public function getWooClient()
{
    if (isset($this->woo_client)) {
        return $this->woo_client;
   } 
    return $this->woo_client = app()->makeWith('WooClient', ['store_id' => $this->store_id,'consumer_key' => $this->consumer_key, 'consumer_secret' => $this->consumer_key]);
}
Poindexter's avatar

Great, it's easier as I first tought. Thank you for your fast reply!

Poindexter's avatar

Your updated reply gives me this error;

Call to a member function app() on null

Any idea what is causing this error?

Please or to participate in this conversation.