Using Laraval Eloquent Models for API Results

There’s a very interesting package called calebporzio/sushi for Laravel that allows one to use arrays as Eloquent drivers / sources of data. @calebporzio posted his own example of using this to front API results here.

It’s a very interesting proof of concept for this use case (probably needs more work and more knobs for production use). So interesting, I had a quick look myself with a bare bones Laravel app:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ laravel new test-sushi
$ cd test-sushi
$ composer require calebporzio/sushi
$ composer require kitetail/zttp
$ php artisan make:model IxpdbProviders
$ laravel new test-sushi $ cd test-sushi $ composer require calebporzio/sushi $ composer require kitetail/zttp $ php artisan make:model IxpdbProviders
$ laravel new test-sushi
$ cd test-sushi
$ composer require calebporzio/sushi
$ composer require kitetail/zttp
$ php artisan make:model IxpdbProviders

The only interesting part of the model, IxpdbProviders, is the getRows() function:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public function getRows()
{
return Cache::remember( 'IxpdbProvider::rows', 3600, function() {
return array_map( function( $a ) {
foreach( $a as $k => $v ) {
if( is_array( $v ) ) {
unset( $a[$k] );
}
}
return $a;
},
Zttp::get('https://api.ixpdb.net/v1/provider/list')->json()
);
});
public function getRows() { return Cache::remember( 'IxpdbProvider::rows', 3600, function() { return array_map( function( $a ) { foreach( $a as $k => $v ) { if( is_array( $v ) ) { unset( $a[$k] ); } } return $a; }, Zttp::get('https://api.ixpdb.net/v1/provider/list')->json() ); });
public function getRows()
{
  return Cache::remember( 'IxpdbProvider::rows', 3600, function() {

    return array_map( function( $a ) {
      foreach( $a as $k => $v ) {
        if( is_array( $v ) ) {
          unset( $a[$k] );
        }
      }
      return $a;
    },
    Zttp::get('https://api.ixpdb.net/v1/provider/list')->json()
  );

});

There’s a few interesting things happening here:

  1. I’m using the cache to store the array result of:
    • the fairly large API response for one hour;
    • the array_map() which is required to remove sub-arrays (sub-objects) within the response as Sushi requires flat rows.
  2. Using Zttp out of curiosity rather than Guzzle directly.
  3. Sushi then takes the array of IXPs (the result of the API call) and stores these in a dedicated in-memory Sqlite database for the duration of the request.

We can now query this as if it were a typical database table:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ php artisan tinker
>>> App\IxpdbProvider::count();
=> 581
>>> App\IxpdbProvider::where( 'name', 'like', 'inex%')->pluck('name')
=> Illuminate\Support\Collection {#3002
all: [
"INEX LAN1",
"INEX LAN2",
"INEX Cork",
],
}
$ php artisan tinker >>> App\IxpdbProvider::count(); => 581 >>> App\IxpdbProvider::where( 'name', 'like', 'inex%')->pluck('name') => Illuminate\Support\Collection {#3002 all: [ "INEX LAN1", "INEX LAN2", "INEX Cork", ], }
$ php artisan tinker

>>> App\IxpdbProvider::count();
=> 581

>>> App\IxpdbProvider::where( 'name', 'like', 'inex%')->pluck('name')
=> Illuminate\Support\Collection {#3002
     all: [
       "INEX LAN1",
       "INEX LAN2",
       "INEX Cork",
     ],
   }