gnugat/marshaller
gnugat/marshaller is a small, framework-agnostic PHP library for marshalling data: it converts arrays into objects and objects back into arrays through configurable builders and extractors, making it easy to map raw input to domain objects in any project.
This assessment reflects v1.1.0, whose headline change is that Marshaller now iterates collections and dispatches each element to the appropriate MarshallerStrategy. That makes the package's primary entry point usable for both single objects and arrays/collections without hand-rolling a loop.
First steps:
Marshaller class and the shipped MarshallerStrategy implementations. The strategy contract is the real API surface you will interact with day-to-day; the Marshaller is mostly orchestration.supports()-style check on each strategy. This determines how much wiring you own.Marshaller from the container, pass a single domain object, and confirm the expected output shape. Then pass an array of the same objects and confirm v1.1.0's collection iteration produces the same per-element output.If you only ever marshal one object type, you can stop after step 4. The collection behaviour matters as soon as you expose lists through an API or export.
Single item vs. collection through one call site. The main win in v1.1.0 is that controllers and actions no longer branch on input type. A common pattern:
public function index(Marshaller $marshaller)
{
return $marshaller->marshal(Order::all());
}
Keep this uniform across endpoints so the iteration behaviour is exercised consistently and bugs surface in one place.
Heterogeneous collections. Because each element is routed to "the appropriate" strategy, you can marshal mixed payloads (e.g. a timeline of OrderCreated, OrderShipped, RefundIssued events) with a single call. This is where the feature earns its keep — model your strategies around output shape rather than around a single aggregate.
Strategy-per-output-contract. Rather than one strategy per model, consider one strategy per consumer: an ApiV1OrderStrategy, an ExportOrderStrategy. The Marshaller picks by element type; your application picks which marshaller/strategy set by context.
Pipeline placement. Marshalling belongs after authorization and validation but before the response is serialised. If you use API Resources or JsonResource, decide early whether the package replaces them or feeds them — running both leads to double mapping and confusing field names.
Testing. Assert on Marshaller output, not on strategy internals. For mixed collections, write one test per element type plus one asserting order and count are preserved.
Marshaller level. Verify [] and empty Collection instances return an empty result rather than throwing or returning null. This is the most likely regression point.Cursor, LazyCollection, and paginator instances are not plain arrays. Confirm the iteration works with them, or call ->items() / ->all() yourself. Eager-load relationships before marshalling to avoid N+1 queries that were previously hidden inside a manual foreach.Marshaller recurses. Assume it does not unless documented, and marshal nested lists explicitly.Marshaller, whose behaviour just changed in a minor release.Marshaller signature and any strategy interface between v1.0 and v1.1.0. The release note describes a behaviour addition, but if the marshal() return type changed from object to array, that is effectively breaking for existing call sites.How can I help you explore Laravel packages today?