5 tips for API Development with Laravel and Fractal

In this article you will read how to set up Application Programming Interfaces (APIs) via Laravel and Fractal.
API Development is one of the things we are strongly committed to at Codana. We like to build strong APIs for different purposes.
When we use Laravel to build an application we always use Fractal.
There are a lot of examples in the documentation and on the internet how this is easy to implement in Laravel.
Here we have listed some recommended practices, which we use in some of our own projects.
What's Fractal for Laravel?
Fractal is a library written by the PHP League, a group that creates open source framework-independent libraries. To make this easy to use within Laravel applications a wrapper is provided.
You use fractal to return consistent responses from your API, to easily convert your data to JSON/YAML, because you send everything systematically through the same transformers you always make sure that data types are consistently the same. This layer between your output and your data models ensures that schema changes do not automatically get through to your API. So you monitor the backwards compatibility of your API much better.
Use the injected service to build responses.
There are facades to make this easier, but by doing so, your IDE can help you build your results.
1
2
3
4
5
6
7
8
9
10
11
12
13
public function __construct(Fractal $fractal)
{
$this->fractal = $fractal;
}
public function respondWithData(User $user): JsonResponse
{
return $this->fractal
->item($user)
->transformWith(new UserDetailsTransformer())
->respond();
}
Use includes where they are useful and reusable transformers.
It is very tempting to build up specific responses by giving extra data from a specific transformer.
In order to maintain as much consistent data as possible to the consumers of the API, it is recommended to reuse transformers where possible.
1
->parseIncludes('user.emailSettings')
Extra data is passed on to the constructor of the transformer.
If you need extra data in a transformer, you can give it to the constructor.
So don't do it this way.
1
2
3
4
// The bad way.
$this->fractal
->item(['data' => $data, 'currentUser' => $user])
->transformWith(new DataForUserTransformer());
It is clearer to do this, you can typehint on `transform` in the DataForUserTransformer (on the two arguments).
1
2
3
// The better way.
$this->fractal->collection($data)
->transformWith(new DataForUserTransformer($user));
Use a NullTransformer where necessary.
Sometimes you build an endpoint that is not strictly restful. For example, an endpoint where the average sales of the past week are calculated. In such cases, you can use a transformer that easily returns what you put in, without the need for other ways of building up responses.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
final class NullTransformer extends TransformerAbstract
{
public function transform(array $data): array
{
return $data;
}
}
class Controller {
public function respondWithData(Request $request): JsonResponse
{
$data = calculateForRequest($request);
return $this->fractal
->item($data)
->transformWith(new NullTransformer())
->respond();
}
}
Eager loading is your best friend.
If you have configured fractal to always require an include, or otherwise display related data, make sure that the eager is loaded before you send it to fractal.
Adding eager loading before sending this data to fractal ensures that the data is already available in memory and does not need to be retrieved from the database on an item-by-item basis. This provides free performance gains for this endpoint.
Conclusion
Fractal always ensures that your code has a better structure and that your API is consistent and easy to consume. By using these tips you can have even more fun.