5

I have 3 functions that get json data from external apis and then saves in my database. Each function is its in own class e.g :

Class api1 {

  public function fetch()
  {
     //Do Something
  }

}

Class api2 {

  public function fetch()
  {
    //Do Something
  }

}

Since its api call might take some time or delay . I want to run all 3 in parallel so that api2 does not have to wait for api1 to complete.

Any way to do that ?

* Note : I'm also going to use laravel scheduler which will run each function every minute or run a single function containing all 3.

J.Adams
  • 133
  • 7
  • you could do it by making 3 queues for each api. If you would like to run them in sequence you can use this: https://laravel.com/docs/5.5/queues#job-chaining – Christophvh Jan 15 '18 at 08:23
  • I write this as a comment because I'm only 90% sure I understand completely. But what you want sounds like `threads` something that does not come out of the box in PHP. However Laravel has something called [`queues`](https://laravel.com/docs/5.5/queues) that will let you use threads with the help of NodeJS. Related: https://stackoverflow.com/questions/36830979/multi-threading-in-laravel – online Thomas Jan 15 '18 at 08:23
  • @Christophvh job chainning its based on chain design pattern so if one job fails the rest will fail. In his case if first call fails the rest will not be executed. – Leo Jan 15 '18 at 08:25

1 Answers1

3

To me this looks more of like callback request for data, so to keep your app from not slowing down this should be a background job.

But before that I would implement an interface for those classes:

interface apiService{

   public function fetch();
}

Class api1 implements apiService {

  public function fetch()
  {
     //Do Something
  }

}

Class api2 implements apiService{

  public function fetch()
  {
    //Do Something
  }

}

Create a job class php artisan make:job dataFetcher

Jobs will be structured under App\Jobs\

The job class in Laravel its dead simple, consisting of a constructor to Inject dependencies and handle() to fire the job.

   protected $service;

   public function __construct(apiService $service)
   {
        $this->service = $service;
   }

   public function handle()
   {
       $this->apiService->fetch();
   }

Note that I am injecting the interface instead of concrete class, using a bit more high level code here. So now you can create a command to fire the calls with a cron job, or you can create a custom service provider to fire the commands as soon as app bootstraps.

I would go with a custom artisan command here:

So just create a custom artisan command on handle method

public function handle()
{
   Job::dispatch(new FirstApiClass);
   Job::dispatch(new SecondApiClass);
}

Handle method will execute first line and Job will be processed in background(doesnt matter if job failed or not), then next call will be fired and so on...

Note the use of the interface in this case, Job class doesnt really care which service you are calling as long as you provide an implmenetation of it.

Leo
  • 7,274
  • 5
  • 26
  • 48