Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel5 Fractal Laravel Package

cyvelnet/laravel5-fractal

Laravel 5 Fractal offers a simple Laravel-friendly wrapper around League Fractal for transforming Eloquent models and collections into clean API responses, with reusable transformers, includes, serializers, and pagination support.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require cyvelnet/laravel5-fractal
php artisan vendor:publish --provider="Cyvelnet\Laravel5Fractal\FractalServiceProvider"

Laravel 5.5+ auto-discovers the provider and Fractal facade. On older versions, register Cyvelnet\Laravel5Fractal\FractalServiceProvider and alias 'Fractal' => Cyvelnet\Laravel5Fractal\Facades\Fractal::class in config/app.php.

Look first at config/fractal.php — the serializer key is the single setting that most affects your JSON shape. Default behavior uses League\Fractal\Serializer\ArraySerializer; switching to DataArraySerializer gives you the conventional {"data": ...} envelope.

Generate a transformer with the bundled command (the main convenience this package adds over raw Fractal):

php artisan make:transformer BookTransformer

It lands in app/Transformers. Fill in transform():

public function transform(Book $book)
{
    return [
        'id'    => (int) $book->id,
        'title' => $book->title,
        'author' => [
            'id'   => (int) $book->author->id,
            'name' => $book->author->name,
        ],
    ];
}

First end-to-end use — a controller returning a single item and a collection:

use Cyvelnet\Laravel5Fractal\Facades\Fractal;

return response()->json(
    Fractal::item($book)->transformWith(new BookTransformer)->toArray()
);

return response()->json(
    Fractal::collection($books)->transformWith(new BookTransformer)->toArray()
);

There is no response macro in this package (unlike spatie/laravel-fractal), so you always wrap in response()->json() yourself.

Implementation Patterns

Item vs. collection. Fractal::item() and Fractal::collection() map to Fractal's Item/Collection resources. Everything else (transformWith, parseIncludes, paginateWith, setMeta, addMeta, toArray) is the underlying League Fractal API you already know — the facade is a thin proxy over a Manager instance.

Includes via query string. This is the standard REST pattern and works out of the box:

$manager = Fractal::parseIncludes(request('include', ''));
return response()->json(
    $manager->collection($books)->transformWith(new BookTransformer)->toArray()
);

The include parameter must match relationship names in the transformer ($this->item($book->author, new AuthorTransformer)). Eager-load them yourself — Fractal does not protect you from N+1:

$books = Book::with($this->parseIncludes(request('include')))->paginate();

Pagination with metadata. Use IlluminatePaginatorAdapter and paginateWith — otherwise the paginator is serialized as a plain array and you lose meta.pagination:

$paginator = Book::paginate(20);
$adapter = new \League\Fractal\Pagination\IlluminatePaginatorAdapter($paginator);

return response()->json(
    Fractal::collection($paginator->getCollection())
        ->paginateWith($adapter)
        ->transformWith(new BookTransformer)
        ->toArray()
);

Serializer strategy. DataArraySerializer is the sane default for JSON APIs. Set it once in the config, and use setSerializer() only when you need a per-endpoint override (e.g. a flat payload for an internal endpoint).

Nested transformers. Keep transformers small and compose them:

public function includeAuthor(Book $book)
{
    return $this->item($book->author, new AuthorTransformer);
}

This is what makes ?include=author work and keeps payloads flexible.

Response shape in one place. Since there is no macro, add a small base controller helper or a JsonResponse macro of your own; do not scatter response()->json(Fractal::...) calls across controllers — you will regret it when the envelope changes.

Caching. Fractal has no cache. Wrap the transformed array with Cache::remember() keyed on the include string, page, and model version/updated_at. Transform after fetching, cache the array, not the Eloquent models.

Gotchas and Tips

  • Serializer mismatch is the #1 surprise. Switching between ArraySerializer and DataArraySerializer changes your payload from {...} to {"data": {...}}. Clients that expect one will break on the other. Pick once, test the shape.
  • Pagination meta is not automatic. Without paginateWith(new IlluminatePaginatorAdapter($p)) you get a plain Collection resource with no meta.pagination. That is expected, not a bug.
  • The include string is user input. Validate it against a whitelist before passing to parseIncludes(); otherwise a typo or malicious value causes ModelNotFoundException or unexpected eager loads. Sanitize with explode(',', request('include')) and intersect.
  • Octane / queue workers: Manager state leaks. Fractal resolves from the container; includes and serializers set during a request can persist into the next on long-running workers. Reset with Fractal::setSerializer(...) and Fractal::parseIncludes([]) (or re-resolve the manager) per request.
  • Default includes in config/fractal.php fire on every transform. If a relationship is not eager-loaded, you get N+1 silently. Keep the default list tiny or empty, and eager-load explicitly.
  • toArray() returns an array, toJson() returns a JSON string. If you then response()->json($string), Laravel double-encodes it. Use toArray() with response()->json().
  • The generator is only a skeleton. It creates the class file and nothing else — no namespace config, no nested transformer scaffolding, no tests. Wire up the app/Transformers namespace in your autoloader as usual (composer autoload picks it up if it's PSR-4 under App\).
  • Not the same as spatie/laravel-fractal. APIs differ (Fractal::item() here vs fractal()->item() there). Do not copy-paste snippets from spatie docs; response()->fractal() does not exist in this package.
  • league/fractal is in maintenance mode. This wrapper is thin enough that migrating off it later means replacing Fractal::item() with (new Manager())->createData(new Item(...)). For new projects consider native Laravel API Resources or spatie/laravel-fractal, which has more activity and a response macro.
  • Version pinning. Last release 2024-03-13; test against your PHP/Laravel combination before adopting, since league/fractal version constraints (^0.20-era) can conflict with other packages.
  • Debugging includes. When a relationship silently disappears, check $request->include is actually populated, the includeXxx method name matches the camelized key, and the transformer extends League\Fractal\TransformerAbstract (not a plain class).
  • Extension point. The provider binds the manager as a singleton; you can extend or bind a custom Fractal class via the container if you need a macro-style response helper of your own.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package