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

noblemfd's avatar

How to consume API in a multi-company application

In my Laravel-5.8 project, I am developing a multi-company application. Now, the source of data for each company is different. Some are api based while some are database based, also some are mixed. Some of the companies have there external api from Azure:

I've been able to consume the api of only one company (employee profile, departments etc):

config/services

'azure' => [
    'client_id' => env('AZURE_KEY','ffrrdd'),
    'client_secret' => env('AZURE_SECRET','ffgh'),
    'redirect' => env('AZURE_REDIRECT_URI','https://company1/login/azure/callback')
],

Also set cron job with guzzle for that company:

    $client = new Client();
    $res = $client->request('GET','httpss://company1/profile/all-employees', [
       'query' => ['key' => 'f197fe11a96d4b5798d8e2a849d8b882']

How do I develop for multiple companies. Since each have different source of API?

Thanks

0 likes
5 replies
martinbean's avatar

@noblemfd I don’t really understand the scenario. Does your application have multiple companies that are customers, and each customer has a unique source of data, but is pulled into your application to do the same thing?

martinbean's avatar
Level 80

@noblemfd In that case, I’d look to create some interfaces that represents what it is your application does; regardless of the company. So if your application fetches a list of employees for a company, then you might have an EmployeeRepository interface, and various implementations of that interface, i.e. DatabaseEmployeeRepository, AzureEmployeeRepository, etc. This is so that, no matter what data source your company uses, your application code remains the same, and even brand new data sources can be introduced at a later data without having to change any of your application’s business logic if it’s just working against interfaces and not concrete implementations.

In terms of selecting the appropriate implementation, there are a couple of ways you could do this. One could be to identify the company in the request (if you’re using route parameters), and then maybe use middleware to bind the correct implementation in the container at runtime:

class ConfigureCompanyServices
{
    protected $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function handle($request, Closure $next)
    {
        $company = $request->route('company'); // Gets company if in route, i.e. /companies/{company}

        $this->container->singleton(EmployeeRepositoryContract::class, function () use ($company) {
            switch ($company->data_source_type) {
                case 'azure':
                    // return new instance of AzureEmployeeRepository
                case 'database':
                    // return new instance of DatabaseEmployeeRepository
                default:
                    throw new InvalidArgumentException(
                        sprintf('Unsupported data source type: %s', $company->data_source_type)
                    );
            }
        });

        return $next($request);
    }
}

With an implementation bound in the container, you’ll then be able to type-hint the repository interface in your classes to get the correct implementation:

class EmployeeController
{
    protected $employeeRepository;

    public function __construct(EmployeeRepository $employeeRepository)
    {
        $this->employeeRepository = $employeeRepository;
    }
}

Alternatively, you could just have methods on your Company model that return the appropriate implementation on demand:

class Company extends Model
{
    public function getEmployeeRepository(): EmployeeRepositoryContract
    {
        switch ($this->data_source_type) {
            case 'azure':
                // return new instance of AzureEmployeeRepository
            case 'database':
                // return new instance of DatabaseEmployeeRepository
            default:
                throw new InvalidArgumentException(
                    sprintf('Unsupported data source type: %s', $company->data_source_type)
                );
            }
    }
}

And then call methods on it in your controllers, etc:

$allEmployees = $company->getEmployeeRepository()->all();
noblemfd's avatar

@martinbean - Thanks so much .

  1. But what what about if two or there companies are using Azure but different APIs?

  2. How do I write the config/services for socialite for multiple companies?

Please or to participate in this conversation.