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

Arya_Svitkona's avatar

Using Eloquent Model with additional data from API

Hi, We are currently using the basic structure of a typical Laravel application with the MVC pattern. Eloquent provides and stores data from mysql database via our Model (ex. Machines).

Now we'd like to use a REST API which provides (and stores) parts of a Machine object. What's the best practise to compose those data from multiple sources, so we can still use the same methods in the controller like find(), create(), etc.?

I think we have to override those methods, but how should we compose those informations.

see Diagram: https://imgur.com/a/Egu9LkV

Machine Data via Eloquent from Database
- software_version
- software_architecture
- firmware_version
- ...
Machine Data from API
- serial_number
- owner_id
- machine_type
- ...
0 likes
3 replies
Tray2's avatar

I would create a job that pulls the data from the api, and stores it in the local db, then query the local table only.

Arya_Svitkona's avatar

That's not possible since the machines will update the data via API on purpose. In the longterm, the database will be replaced by the API.

I have a possible solution by using the Repository Pattern and provide a different Repository, but I still have the problem, that I must compose data from two sources (which should done in the model, if I'm right).

Arya_Svitkona's avatar

If anyone is interested, here is our approach.

We created an service for retrieving the data from REST API (https://martinjoo.dev/working-with-3rd-parties-in-laravel) and after that an own service for each "group of endpoints" (ex. user, machines, customers, etc.). Inside the machineService we retrieve data via Eloquent from the database and also from the REST API via the restApiService.

We merge those collections with following helper functions and return the combined data.

if(! function_exists('extendCollectionByKey')) {
    /**
     * Merge second collection to first collection matched by key
     *
     * @param  string  $key
     * @param  Collection  $collection1
     * @param  Collection  $collection2
     * @param  string|null  $key2
     * @return Collection
     */
     function extendCollectionByKey(string $key, Collection $collection1, Collection $collection2, string $key2 = null): Collection {
        $array1 = array_map(static fn($item) => (array)$item, $collection1->toArray());
        $array2 = array_map(static fn($item) => (array)$item, $collection2->toArray());
        $key2 = $key2 ?? $key;

        $newArray = [];
        $map = array_column($array2, null, $key2);
        foreach ($array1 as $item) {
            $itemAsArray = $item;
            $data = $map[$itemAsArray[$key] ?? false] ?? false;
            if ($data === false) {
                $data = [];
            }
            $newArray[] = (object) array_merge($itemAsArray, $data);
        }

         return collect($newArray);
    }
}

example use:

public function allMachines():Collection{
        $apiMachines = $this->restApiService->getAllMachines();
        $databaseMachines = $this->machineRepository->all();

        return extendCollectionByKey('serial_number', $apiMachines, $databaseMachines);
    }

Please or to participate in this conversation.