PHP Fractal – Make Your API's JSON Pretty, Always! — SitePoint – SitePoint
This article was peer reviewed by Viraj Khatavkar. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!
If you’ve built an API before, I’ll bet you’re used to dumping data directly as a response. It may not be harmful if done right, but there are practical alternatives that can help solve this small problem.
One of the available solutions is Fractal. It allows us to create a new transformation layer for our models before returning them as a response. It’s very flexible and easy to integrate into any application or framework.
We will be using a Laravel 5.3 app to build an example and integrate the Fractal package with it, so go ahead and create a new Laravel app using the installer or via Composer.
or
Then, inside the folder, we require the Fractal package.
Our database contains a
users
and roles
table. Every user has a role, and each role has a list of permissions.We’re going to create a transformer for each model. Our
UserTransformer
class looks like this:Yup, that’s all it takes to create a transformer! It just transforms the data in a way that can be managed by the developer, and not left to the ORM or the repository.
We extend the
TransformerAbstract
class and define the transform
method that will be called with a User
instance. The same thing goes for the RoleTransformer
class.Our controllers should transform the data before sending it back to the user. We’re going to work on the
UsersController
class and only define the index
and show
actions for the moment.The index action will query all users from the database, create a resource collection with the list of users and the transformer, and then perform the actual transformation process.
Of course, it doesn’t make sense to return all the users at once, and we should implement a paginator for this.
Laravel tends to make things simple. We can accomplish pagination like this:
But to make this work with Fractal, we may need to add a little bit more code to transform our data before calling the paginator.
The first step is to paginate data from the model. Next, we create a resource collection like before, and then we set the paginator on the collection.
Fractal provides a paginator adapter for Laravel to convert the
LengthAwarePaginator
class, and it also has one for Symfony and Zend.Notice that it adds extra fields for pagination details. You can read more about pagination in the documentation.
Now that we’ve become familiar with Fractal, it’s time to learn how to include sub-resources (relations) with the response when it’s requested by the user.
We can request extra resources to be included with the response like this
http://demo.vaprobash.dev/users?include=role
. Our transformer can automatically detect what’s being requested and parse the include
parameter.The
$availableIncludes
property tells the transformer that we may need to include some extra data with the response. It will call the includeRole
method if the include
query parameter is requesting the user roles.The
$this->fractal->parseIncludes
line is responsible for parsing the include query parameter. If we request the list of users we should see something like this:If every user had a list of roles, we could change the transformer to be like this:
When including a sub-resource, we can nest relations by using the a dot notation. Let’s say every role has a list of permissions stored in a separate table and we wanted to list users with their role and permissions. We can do it like this
include=role.permissions
.Sometimes, we are required to include some necessary relations by default, like an address relation for example. We can do that by using the
$defaultIncludes
property inside the transformer.One of the things I really love about the Fractal package is the ability to pass parameters to include parameters. A good example from the documentation is
order by
. We can apply it to our example like so:The important part here is
list($orderCol, $orderBy) = $paramBag->get('order') ?: ['created_at', 'desc'];
, this will try to get the order parameter from the users include and will apply it to the query builder.We can now order our included users list by passing parameters (
/roles?include=users:order(name|asc)
). You can read more about including resources in the documentation.But, what if the user didn’t have any roles attached? It will halt with an error because it was expecting valid data instead of null. Let’s make it delete the relation from the response instead of showing it with a null value.
Because Eloquent will lazy load models when accessing them, we may encounter the n+1 problem. This can be solved by eager loading relations at once to optimize the query.
This way, we won’t have any extra queries when accessing model relations.
I came across Fractal while reading the Building APIs you won’t hate by Phil Sturgeon, which was a great and informative read that I wholeheartedly recommend.
Do you use transformers when building your API? Do you have any preferred package that does the same job, or do you just dump the
json_encode
s? Let us know in the comments section below!PHP Fractal is a powerful tool that helps in presenting and transforming data for APIs. It is important because it provides a standardized way to output complex, nested data structures, ensuring that your API’s data output is consistent, well-structured, and easy to understand. This makes it easier for developers to work with your API and reduces the likelihood of errors.
PHP Fractal works by taking complex data structures and transforming them into a more consumable format. It does this through two main components: Transformers and Serializers. Transformers are responsible for converting the complex data into a simpler format, while Serializers format the final output.
Transformers in PHP Fractal are classes that define how data from your application should be outputted in the API response. They take complex data structures and transform them into simpler, more consumable formats. This allows you to control exactly what data is included in the API response and how it is structured.
Serializers in PHP Fractal are responsible for formatting the final output of your API. They take the data that has been transformed by the Transformers and format it into a specific structure. This allows you to ensure that your API’s output is consistent and easy to understand.
Implementing PHP Fractal in your project involves installing the Fractal library via Composer, creating Transformers for your data, and then using the Fractal class to transform your data using the Transformers. You can then output the transformed data using one of Fractal’s Serializers.
Yes, PHP Fractal is a standalone library that can be used with any PHP project. It is not tied to any specific framework or platform, making it a versatile tool for any PHP developer.
Using PHP Fractal provides several benefits. It ensures that your API’s output is consistent and well-structured, making it easier for developers to work with. It also provides a standardized way to transform complex data structures, reducing the likelihood of errors and making your code easier to maintain.
PHP Fractal stands out for its simplicity and flexibility. It provides a straightforward way to transform complex data structures, and its use of Transformers and Serializers allows for a high degree of customization. This makes it a powerful tool for any developer working with APIs.
Yes, PHP Fractal is highly customizable. You can create custom Transformers to control exactly how your data is transformed, and you can use different Serializers to format the output in different ways. This allows you to tailor the output of your API to meet your specific needs.
There are many resources available to learn more about PHP Fractal. The official PHP League website provides comprehensive documentation, and there are numerous tutorials and blog posts available online. Additionally, the PHP Fractal GitHub repository is a great place to explore the code and see examples of how it can be used.
Younes is a freelance web developer, technical writer and a blogger from Morocco. He's worked with JAVA, J2EE, JavaScript, etc., but his language of choice is PHP. You can learn more about him on his website.
© 2000 – 2024 SitePoint Pty. Ltd.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
source