spawnrad/data-bundle
Spawnrad Data Bundle offers a simple way to organize, group, and transport structured data within Laravel applications. Define reusable data bundles and move data cleanly between layers using a lightweight, framework-friendly API.
Read the repo before you install it. The description ("Extension pour les rs") tells you nothing usable, there is no README-level scope, and there are zero stars and zero dependents — so no one has written the blog post you are about to look for. Budget an hour to read the source directly. In this order:
composer.json — the require block is the single most important file. Look for symfony/framework-bundle or symfony/dependency-injection (this is a Symfony bundle and will not drop into Laravel as-is) versus illuminate/support / illuminate/contracts (Laravel-compatible). The Bundle suffix and the SPDataBundle class name point strongly at Symfony; confirm before you plan anything.src/ — find the bundle entry class (typically *Bundle.php extending Bundle, with an optional getContainerExtension()), the DependencyInjection/ folder (the real feature surface is usually in Configuration.php + *Extension.php), and any Resources/config/services.yaml|xml. That config tree is the de-facto API.tests/ and the git tags. A green test suite and a tag history change this from "unvetted code" to "forkable small library."Install (Symfony path). If it is a Symfony bundle:
composer require spawnrad/data-bundle
Register it in config/bundles.php:
return [
// ...
Spawnrad\DataBundle\SPDataBundle::class => ['all' => true],
];
If it ships a bundle extension, a config file may also be required under config/packages/, typically:
# config/packages/sp_data.yaml
sp_data: ~
The exact root key comes from DependencyInjection/Configuration.php — use the root node name defined there, not a guessed one.
Install (Laravel path). Only proceed if composer.json requires illuminate/support and ships a *ServiceProvider. If it is a pure Symfony bundle, do not try to pull it into a Laravel app — you would pull the Symfony DI/HttpKernel stack behind it for no benefit and create a version-conflict trap. The Laravel-friendly description is likely aspirational marketing, not evidence of compatibility; treat it as a claim to verify against composer.json.
First use case. The package advertises "typed data objects with array/JSON conversion." That means the smallest useful smoke test is: define a bundle (a typed class extending or implementing whatever base the package exposes), populate it, convert it to array, then to JSON, then back. That round-trip is the whole value proposition and it is what you should prove first — not a full integration into a controller. If the round-trip does not behave predictably (key ordering, nulls, nested bundles, date handling), that is the signal to stop and reimplement in twenty lines rather than fight an unmaintained dependency.
Centralize payload shape, not payload creation. The one pattern worth copying from this package into your app is the "typed bundle as the single source of truth for a payload contract." Use the bundle class to declare the shape — properties, types, conversion methods — and keep construction in your services. This gives you one place to change when an API contract changes, which is the actual win, whether or not you keep the package.
// The pattern, not a guaranteed package API — adapt to the base class you find in src/.
final class InvoiceBundle extends DataBundle
{
public function __construct(
public readonly string $number,
public readonly int $amountCents,
public readonly ?string $note = null,
) {}
}
$bundle = new InvoiceBundle('INV-1024', 4999);
$payload = $bundle->toArray(); // stable shape for an API response
$json = $bundle->toJson(); // or json_encode($bundle->toArray())
Wrap it behind a thin adapter before first use. Do not call bundle classes directly from controllers. Introduce one internal interface (PayloadInterface with toArray()/toJson()) and have the bundle implement or be wrapped by it. This is the difference between a one-day migration to a replacement and a week-long refactor when you discover the package is dead. It costs an hour up front and pays out on every future change.
Use it as a boundary object, not a domain model. Data bundles are for the edge of your app — request validation boundaries, API responses, queue payloads, event DTOs. Do not let them grow methods that reach into services or the container. The moment a bundle starts doing I/O, you have coupled your data shape to infrastructure and lost the substitutability you were after.
Prefer array conversion for framework boundaries. Eloquent toArray(), JSON responses, and job payloads all want arrays. Build the toArray() output once, reuse it for toJson(), and keep a single test asserting the exact shape. This is the pattern the package's Array/JSON conversion claim is trying to sell — implement it deliberately instead of via json_encode($obj) scattered across controllers.
Register and inject via the container when you can. If the bundle exposes services in DependencyInjection/, prefer constructor injection over app()/ContainerInterface::get() lookups. In Symfony, verify with debug:container; in Laravel, check that the service provider's register() actually binds anything (many stub providers only publish config and bind nothing useful).
Extend transformations, don't fork the base class. If the package offers a transformation hook (a transform() method, a normalizer, or a serialization interface), add custom behavior there rather than editing core files. You want custom logic in one location so that when you eventually fork — and you will — the diff is small.
The framework mismatch is the first trap. A Symfony bundle installed into a Laravel app will autoload fine and then fail at runtime with confusing "class not found" or container-binding errors, because the Symfony DI/framework stack is not present. Verify composer.json before anything else.
composer require succeeding is not proof of compatibility. With zero dependents there is no community evidence the version constraints in composer.json were ever tested against your framework release. Check the require block against your pinned PHP version and framework major; assume the constraints overstate support.
No docs means the config tree is the contract. If you are guessing config keys, open DependencyInjection/Configuration.php. Symfony will throw a InvalidConfigurationException naming unknown keys on boot; in Laravel you may get silent no-ops instead. Debug by dumping the resolved config, not by reading the (missing) README.
PSR-4 autoload correctness. Check the autoload.psr-4 mapping in composer.json matches the actual directory/namespace. A mismatch is common in low-activity repos and presents as mysterious "class not found" after composer require — fix by composer dump-autoload -o and inspecting the generated map.
Fork it on day one if you adopt. Zero stars, zero dependents, and a truncated description mean upstream maintenance is effectively zero. Pin to your own fork (or a pinned commit SHA) and vendor the code. That eliminates the abandonment risk and lets you patch framework-compat breaks yourself. Do not composer require a floating constraint against this repo.
Beware a post-install script or unexpected transitive dependency. Run composer show --tree spawnrad/data-bundle and read the install scripts before any production install. With no community scrutiny, source review is your only supply-chain control.
Silent null / key-order behavior is the most likely bug in array↔JSON conversion. Write a round-trip test immediately (bundle → array → JSON → array → compare) covering nullable fields, nested bundles, and date values. If the round-trip is not stable, treat that as the kill criterion for the spike.
Do not put it on a critical path. For anything revenue- or customer-facing, either reimplement the array/JSON conversion in a small internal DTO base class (this is genuinely twenty lines) or wrap the package behind an adapter so a swap is trivial. The package is fine as reference material and fine as a fork we own, but it is not a dependency to trust with a delivery date.
Extension points worth checking. Look for a base class or interface you can implement (DataBundleInterface, a NormalizerInterface, a transform() hook). These are where you should add custom logic. If there are none, the package offers less than writing your own base class — which is the moment to stop the spike.
How can I help you explore Laravel packages today?