Product Decisions This Supports
-
Reducing Boilerplate & Improving Developer Velocity
- Eliminates repetitive manual mapping code (e.g., DTOs, API responses, view models) by automating property transfers, including private/protected fields.
- Enables faster iteration for teams working with complex object hierarchies (e.g., domain models → API contracts, database entities → frontend state).
- Roadmap tie-in: Justifies investment in self-service data transformation for backend services, reducing reliance on shared libraries or custom scripts.
-
Build vs. Buy: Avoid Custom Solutions
- Replaces ad-hoc mapping logic (e.g., nested
foreach loops, manual property assignments) with a maintained, feature-rich alternative.
- Avoids reinventing wheel for polymorphic mappings, nested objects, or custom business logic in transformations.
- Cost savings: Reduces tech debt from scattered mapping code (e.g., in services, controllers, or repositories).
-
API/Integration Layer Efficiency
- Standardizes data contracts between microservices, databases, and clients (e.g., GraphQL → DTOs, REST → internal models).
- Supports automated serialization/deserialization for APIs, reducing manual JSON/XML mapping in controllers.
- Example use case: Map a Doctrine entity to a JSON:API payload with minimal configuration.
-
Testing & Maintainability
- Centralized mapping rules make transformations predictable and easier to test (vs. scattered logic).
- Enables reverse mappings (e.g., DTO → entity updates) with consistent conventions.
- DevOps impact: Simplifies CI/CD by reducing flaky tests caused by inconsistent manual mappings.
-
Extensibility for Complex Scenarios
- Custom operations allow integration with domain-specific logic (e.g., encrypting fields, applying business rules during mapping).
- Supports context-aware mappings (e.g., tenant-specific transformations, audit logging during mapping).
- Future-proofing: Aligns with Laravel’s ecosystem (e.g., integrates with Symfony bundles, Eloquent models).
When to Consider This Package
Adopt This Package If:
- Your team spends >10% of backend dev time writing manual mapping logic (e.g., DTOs, API responses).
- You have deep object hierarchies (e.g., nested entities, polymorphic relationships) that require consistent transformations.
- You need reverse mappings (e.g., updating entities from DTOs) or dynamic property resolution (e.g., snake_case ↔ camelCase).
- Your project uses Laravel/Eloquent and could benefit from standardized data contracts between layers.
- You want to reduce technical debt from scattered mapping code (e.g., in services, repositories, or controllers).
- Your team prioritizes developer experience (e.g., reducing cognitive load for junior devs).
Look Elsewhere If:
- Your mappings are trivial (e.g., 1:1 property copies with no custom logic).
- You’re using PHP 8.1+ attributes (consider
spatie/laravel-data for declarative DTOs).
- Your stack is non-PHP (e.g., Node.js, Python) or heavily relies on serialization libraries (e.g., JMS Serializer).
- You need real-time performance optimization (this library adds minor overhead; benchmark for your use case).
- Your team prefers runtime-generated code (e.g., Doctrine Instantiator + manual mapping).
How to Pitch It (Stakeholders)
For Executives:
*"AutoMapper+ is a productivity multiplier for our backend team. By automating the tedious work of converting between objects (e.g., database records → API responses), we can:
- Ship features 20% faster by eliminating repetitive boilerplate.
- Reduce bugs from inconsistent manual mappings across services.
- Lower maintenance costs by centralizing transformation logic in one place.
For example, if our API team currently spends 2 hours/week writing DTO mappings, this could save ~50 hours/year per developer—time better spent on core business logic. It’s a low-risk, high-reward investment with minimal upfront cost (MIT license, active maintenance)."*
For Engineering Leaders:
*"This solves a painful, scalable problem in our codebase:
- No more copy-pasted mapping logic in controllers/repositories.
- Supports complex scenarios out of the box (nested objects, polymorphic types, custom business rules).
- Integrates seamlessly with Laravel/Eloquent, requiring minimal setup.
Trade-offs:
- Adds ~50ms overhead per mapping (negligible for most APIs).
- Requires initial setup (registering mappings), but pays off long-term.
Recommendation: Pilot in one service (e.g., User API) to measure impact on dev velocity. If successful, roll out to other teams."*
For Developers:
*"Say goodbye to this:
$dto = new UserDto();
$dto->name = $user->getFullName();
$dto->age = date('Y') - $user->getBirthYear();
$dto->roles = array_map(fn($role) => $role->getName(), $user->getRoles());
With AutoMapper+, it’s just:
$mapper->map($user, UserDto::class);
Key perks:
- Handles private/protected properties automatically.
- Supports nested mappings (e.g.,
User → UserDto → AddressDto).
- Custom logic via callbacks (e.g.,
forMember('age', fn($user) => ...)).
- Reverse mappings for updates (e.g.,
UserDto → User).
Getting started:
- Install:
composer require mark-gerarts/auto-mapper-plus.
- Register mappings in a config file (e.g.,
app/Config/AutoMapper.php).
- Use
$mapper->map($source, Destination::class) anywhere.
Pro tip: Pair with Laravel’s service container to auto-resolve the mapper in controllers/services."*