If you ever developed for an API, you might have had troubles with changes of your database schema. If you didn’t happen to have a good implementation, you had to rework your whole model when changing some column names. In this article I will demonstrate how you can use Fractal as a layer between your models and JSON output. This post will show you how this package will make API development easier.

Fractal as a package

Fractal is a project written in PHP, and part of The League of Extraordinary Packages. These packages all comply to several requirements, like usage of PHP-FIG and Unit Test coverage. Fractal is mainly developed by Phil Sturgeon and still receives regular improvements. It can also be used with Composer.

Setting up an environment

For demonstration purposes, I will now set up a framework using Silex and Illuminate/Database (the ORM component of Laravel). It doesn’t matter if you don’t have any experience with one of those. The things I will do are very straightforward and I will explain them as much as I can. If something is unclear do not hesitate to leave a comment. I will now set up a framework. Note that if you don’t want to follow the steps, you can download all the code at the end of the article. Now start with creating a new folder inside root folder. We’ll start with creating our composer.json file, with all the dependencies that we need. In our case: Silex and Illuminate\Database. Create a composer.json file like this:
{
"require": {
"silex/silex": "~1.2",
"illuminate/database": "*"
},
}
Install the packages with composer install.

The database

I will take the example of an online music database. The database will provide information for several songs: the songname, the artist name, artist website, album name, release date and music label. In the beginning this will all be in one table. If you want to try it out yourself download the file 1.sql from this article’s repository and run it on your database.

The code

In order to use Silex with Illuminate\Database, we’ll need some code. Inside the app folder create a new file index.php. This is where we’ll start Silex, connect to the database and define routes:
<?php
require("../vendor/autoload.php");

$app = new Silex\Application();

$app['database'] = require("database.php");

$app->mount('/tracks', include 'controllers/tracks.php');

$app->run();
On the first line we require the autoload file for composer. Then we create a new Silex application and load in Illuminate/Database. We then create a controller for /tracks so that all URLs which start with /tracks will be handled by controllers/tracks.php. The database.php file looks like this, don’t forget to change the connection settings:
<?php
use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule;

$capsule->addConnection([
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'musicstore',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
]);

use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;
$capsule->setEventDispatcher(new Dispatcher(new Container));

$capsule->setAsGlobal();

$capsule->bootEloquent();

return $capsule;

First API version

Initially, the database only contains one table (import 1.sql). This table contains information about the track itself (title, music label), the album (title and release date), and the artist (name and website). Our API will provide two things: when navigating to /tracks, it will output a json list with the track ids, their title and artist. When navigating to /tracks/$id, it will output all the track information as a json object.

Tracklisting

We begin with the list of tracks. Put this code comes into /controllers/tracks.php
:
<?php

$tracks = $app['controllers_factory'];

$tracks->get('/', function() use ($app)
{
$tracklist = Track::getTrackList();
$output = array("data" => $tracklist);
return json_encode($output);
});

return $tracks;
and this code for the model, /models/Track.php:
public static function getTrackList()
{
return Track::select('id','name','artist_name')->get();
}
This uses the Illuminate\Database querybuilder to get a list of id’s, names and articles and then outputs them. The output will have this format:
{
data: [
{
id: 1,
name: "Song 1",
artist_name: "Artist 1"
},
{
id: 2,
name: "Song 2",
artist_name: "Artist 2"
}
]
}
This works as expected, but if the table schema changes, so will the JSON output. We will now use a Fractal transformer to force a specific structure of output. This Transformer is a class that extends Fractal\TransformerAbstract. Create a new folder for transformers in your app folder with the name transformers. The first transformer is TracklistTransformer.php which we’ll use solely for /tracks, and it looks like this:
<?php
namespace Musicstore;

class TracklistTransformer extends \League\Fractal\TransformerAbstract
{
public function transform(Track $track)
{
return [
'id' => (int) $track->id,
'title' => $track->title,
'artist' => $track->artist_name
];
}
}
Every transformer requires a transform() method, with its argument being the object you want to transform, in our case an instance of the class Track. In the return statement the structure is defined as an associative array. We’ll now apply the transformation and create the output array by using a Serializer. We are about to use the DataArraySerializer because this will put our data under the data-key in the JSON object. This allows you to have other information in your response like status codes or error messages. In order to use this serializer, we’ll need an instance of the manager class. I will use the DI container for this so that we don’t have to rewrite boilerplate code every time. The new /controllers/tracks.php file looks like this:
<?php

$tracks = $app['controllers_factory'];

$tracks->get('/', function() use ($app)
{
$tracks = Track::getTrackList();
$tracklist = new \League\Fractal\Resource\Collection($tracks, new TracklistTransformer);
$output = $app['serializer']->createData($tracklist)->toArray();
return json_encode($output);
});

return $tracks;
We use $tracklist = new \League\Fractal\Resource\Collection($tracks, new TracklistTransformer); to apply the transformation. In this route we are using a collection of tracks: our $tracks variable is an object of the class Illuminate\Database\Eloquent\Collection. This class is compatible with Fractal and its transformers. For the other route we’re going to use a transformer on a single table item. But more on that later. For using $app['serializer'], place this code in index.php, right under the app['database'] statement:
$app['serializer'] = $app->share(function()
{
$manager = new \League\Fractal\Manager();
$manager->setSerializer(new League\Fractal\Serializer\DataArraySerializer());
return $manager;
});
Now you have a working tracklisting.

Track information

I will now quickly demonstrate how to show information about specific tracks and then make edits to the data schema with Fractal. Open controllers/tracks.php and add the following code above the return statement:
<?php
$tracks->get('/{id}', function($id) use ($app)
{
return Track::find($id);
});
Track::find($id)
returns an object of class Track with its id matching the URL. Again this works but it’s not a good way, so we will implement Fractal. Create a new transformer transformers/TrackTransformer.php:
<?php
namespace Musicstore;

class TrackTransformer extends \League\Fractal\TransformerAbstract
{
public function transform(Track $track)
{
return [
'id' => (int) $track->id,
'title' => $track->title,
'artist_name' => $track->artist_name,
'artist_website' => $track->artist_website,
'album_name' => $track->album_name,
'album_release' => $track->album_release,
'album_label' => $track->album_label
];
}
}
In your controller edit the route to this:
$tracks->get('/{id}', function($id) use ($app)
{
$track = Track::find($id);
$track = new \League\Fractal\Resource\Item($track, new TrackTransformer);
$output = $app['serializer']->createData($track)->toArray();
return json_encode($output);
});
As you can see it is rather similar to the previous route, except that in this case we’re not dealing with a Collection but a single Item. If you are using 1.sql you can navigate to localhost/app/tracks/1 and see some sample data.

Updated API version

Our music store wants to expand and provide more information about the artists and the albums. In the new database schema there are separate tables for the artists and the albums. You can download 2.sql to use the new schema. The tables look like this: TRACKS:
  • id
  • title
  • artist_id
  • album_id
ARTISTS:
  • id
  • name
  • website
ALBUMS:
  • id
  • name
  • release
  • label
In the tracks table, the artist and album columns are integers which correspond to rows in the respective tables. We’ll use the tranformers to keep our output structure the same. In order to make things easier we’ll use some features of Illuminate\Database. Go inside models/Track.php and add two more methods:
public function artist()
{
return $this->belongsTo('\Musicstore\Artist');
}

public function album()
{
return $this->belongsTo('\Musicstore\Album');
}
If we have a Track object we can access its Album and Artist by using $track->album and $track->artist. First we need to make those models so create two files models/Artist.php and models/Album.php:
// models/Artist.php
<?php
namespace Musicstore;
class Artist extends \Illuminate\Database\Eloquent\Model
{
public function tracks()
{
return $this->hasMany('\Musicstore\Track');
}
}

// models/Album.php
<?php
namespace Musicstore;
class Album extends \Illuminate\Database\Eloquent\Model
{
public function tracks()
{
return $this->hasMany('\Musicstore\Track');
}
}
The last thing we have to do now is edit our transformers:
// transformers/TrackTransformer.php
return [
'id' => (int) $track->id,
'title' => $track->title,
'artist_name' => $track->artist->name,
'artist_website' => $track->artist->website,
'album_name' => $track->album->name,
'album_release' => $track->album->release,
'album_label' => $track->album->label
];

// transformers/TracklistTransformer.php
return [
'id' => (int) $track->id,
'title' => $track->title,
'artist' => $track->artist->name
];
If you test everything out, you’ll see that it works.

Conclusion

As I’ve demonstrated, you can, by adding Fractal before your output, easily perform database changes, without the end user noticing. You can download the full example code here at my repository. If something is unclear please do not hesitate to leave a comment.

Frequently Asked Questions (FAQs) about Fractals

What are the practical applications of fractals?

Fractals are not just mathematical concepts or beautiful patterns. They have practical applications in various fields. In computer graphics, fractals are used to create detailed images and textures. In nature, they help us understand and model complex systems like weather patterns, landscapes, and biological systems. In the field of medicine, they are used to model and analyze human physiology. Fractals are also used in data compression algorithms, antenna design, and in creating digital art.

How are fractals used in computer graphics?

In computer graphics, fractals are used to create complex, detailed, and realistic images. They are particularly useful in creating natural-looking textures and landscapes. For instance, the intricate patterns of a tree or a mountain range can be modeled using fractals. This is because fractals can create complex shapes from simple rules, which is a characteristic of many natural phenomena.

Can fractals be used to model human physiology?

Yes, fractals can be used to model and analyze human physiology. For instance, the branching patterns of blood vessels and the structure of the lungs can be modeled using fractals. This is because these structures exhibit self-similarity, a key characteristic of fractals. By using fractals, researchers can gain insights into the functioning of these systems and develop better treatments.

What is the Fractal Code in Digimon?

In the Digimon universe, the Fractal Code is a digital code that forms the essence of a Digimon. It is a sequence of data that can be visualized as a fractal pattern. When a Digimon is defeated, its Fractal Code is revealed. Another Digimon can absorb this code to gain power or restore the defeated Digimon.

How are fractals used in data compression?

Fractals are used in data compression algorithms due to their ability to represent complex data in a compact form. A fractal compression algorithm uses the self-similarity property of fractals to identify and store repeating patterns in the data. This allows the data to be represented in a much smaller form, making it easier to store and transmit.

What is the Fractal of the Mists in Guild Wars 2?

The Fractal of the Mists is a special type of dungeon in the game Guild Wars 2. It consists of multiple mini-dungeons, each with its own unique challenges and rewards. The difficulty of the Fractal of the Mists scales with the player’s level, making it a challenging and rewarding experience for players of all levels.

How are fractals used in antenna design?

In antenna design, fractals are used to create compact and efficient antennas. A fractal antenna uses the self-similarity property of fractals to create an antenna that has a large effective length but a small physical size. This allows the antenna to operate at multiple frequencies, making it versatile and efficient.

How are fractals used in digital art?

In digital art, fractals are used to create intricate and beautiful patterns. Artists use fractal-generating software to create these patterns, which can then be manipulated and colored to create stunning artworks. The infinite complexity and self-similarity of fractals make them a powerful tool for digital artists.

Can fractals be used to model weather patterns?

Yes, fractals can be used to model complex weather patterns. The chaotic and complex nature of weather systems makes them difficult to model using traditional methods. However, the self-similarity and complexity of fractals make them a suitable tool for modeling these systems.

What is the nature of fractal code?

The nature of fractal code is that it is a sequence of data that can be visualized as a fractal pattern. This code can represent complex data in a compact form, making it useful in various applications such as data compression, computer graphics, and digital art. The self-similarity property of fractals allows the code to represent complex patterns and structures.

SitePoint SponsorsSitePoint Sponsors
View Author
apidatabasefractaljsonleagueOOPHPPHPphpleaguewalkthrough
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week