Weave Code
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

Entity Response Control Laravel Package

codememory/entity-response-control

Define response prototypes to shape arrays from Doctrine entities using PHP attributes. Build API-friendly payloads with custom formatting, naming strategies, and decorators, including extra per-object data from additional queries.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require codememory/entity-response-control
    
  2. Basic Setup Initialize the ResponsePrototypeManager with required dependencies (cache, reflector, factories, and decorators):

    use Codememory\EntityResponseControl\ResponsePrototypeManager;
    use Codememory\Reflection\ReflectorManager;
    use Symfony\Component\Cache\Adapter\FilesystemAdapter;
    
    $cache = new FilesystemAdapter('codememory', ['directory' => storage_path('cache')]);
    $reflectorManager = new ReflectorManager($cache);
    $manager = new ResponsePrototypeManager(
        $reflectorManager,
        new PrototypeExecutionContextFactory(new PropertyWrapperFactory()),
        new PropertyExecutionContextFactory(),
        new BaseCollector(new DecoratorRegistrar(), new SnakeCamelNamingStrategy()),
        new DecoratorRegistrar()
    );
    
  3. First Use Case Define a prototype class (e.g., UserPrototype) with properties matching your entity structure, then collect data:

    class UserPrototype {
        private ?string $name = null;
        private ?string $surname = null;
    }
    
    $user = new User(); // Your entity
    $result = $manager->collect(UserPrototype::class, $user);
    

Implementation Patterns

Core Workflow

  1. Prototype Design

    • Create a class with properties mirroring the desired API response structure.
    • Use PHP attributes (e.g., #[Property\Getter]) to map entity methods to prototype properties.
    • Example:
      class PostPrototype {
          #[Property\Getter('getTitle')]
          private ?string $title = null;
      
          #[Property\Getter('getPublishedAt')]
          #[Property\DateFormat('Y-m-d')]
          private ?string $publishedAt = null;
      }
      
  2. Nested Collections Handle relationships (e.g., UserOrder) with #[Property\Nested]:

    class UserPrototype {
        #[Property\Nested(OrderPrototype::class)]
        private array $orders = [];
    }
    
  3. Metadata Integration Combine entity data with external metadata (e.g., analytics) using #[Property\FromObjectMetadata]:

    class UserPrototype {
        #[Property\FromObjectMetadata('getId', 'success_orders')]
        private ?int $successOrders = null;
    }
    $result = $manager->collect(UserPrototype::class, $users, ['success_orders' => [...]]);
    
  4. Dynamic Metadata via Callbacks Fetch metadata dynamically via services:

    #[Prototype\Callback([AnalyticsService::class, 'fetchUserStats'])]
    class UserPrototype { ... }
    

Laravel Integration Tips

  • Service Provider Bind the manager to Laravel’s container for dependency injection:

    public function register(): void {
        $this->app->singleton(ResponsePrototypeManager::class, fn($app) => new ResponsePrototypeManager(
            new ReflectorManager($app['cache']->getAdapter('codememory')),
            // ... other dependencies
        ));
    }
    
  • API Responses Use in controllers to transform entities:

    public function show(User $user) {
        $prototype = $this->manager->collect(UserPrototype::class, $user);
        return response()->json($prototype);
    }
    
  • Caching Leverage Symfony’s cache adapter (e.g., FilesystemAdapter) for reflection caching to improve performance.


Gotchas and Tips

Pitfalls

  1. Attribute Parsing

    • Issue: Attributes like #[Property\Getter] must be imported explicitly (e.g., use Codememory\EntityResponseControl\Decorators\Property).
    • Fix: Ensure all decorators are fully qualified or aliased.
  2. Metadata Mismatches

    • Issue: If FromObjectMetadata keys don’t match entity getter values, properties will default to null.
    • Fix: Validate metadata structure before passing to collect().
  3. Nested Collection Handling

    • Issue: Nested prototypes (#[Property\Nested]) require the nested prototype class to exist and be properly configured.
    • Fix: Test nested structures incrementally.
  4. Cache Invalidation

    • Issue: Reflection cache may stale if prototype classes change without clearing the cache.
    • Fix: Clear cache after schema updates:
      $cache->clear();
      

Debugging Tips

  • Enable Debug Mode Temporarily disable caching in ReflectorManager for live debugging:

    $reflectorManager = new ReflectorManager(null); // Disables cache
    
  • Inspect Execution Context Use PrototypeExecutionContextInterface to debug metadata or decorators:

    $manager->collect(UserPrototype::class, $user, fn($context) => $context->setMetadata([...]));
    

Extension Points

  1. Custom Decorators Extend functionality by creating new decorators (e.g., #[Property\CustomFormat]):

    use Codememory\EntityResponseControl\Interfaces\PropertyDecoratorInterface;
    
    class CustomFormatDecorator implements PropertyDecoratorInterface { ... }
    
  2. Naming Strategies Override default naming (e.g., SnakeCamelNamingStrategy) for API consistency:

    $manager = new ResponsePrototypeManager(..., new CustomNamingStrategy());
    
  3. Collectors Replace BaseCollector to implement custom logic (e.g., filtering, transformations):

    class CustomCollector extends BaseCollector { ... }
    

Performance

  • Batch Processing For large collections, process in chunks to avoid memory issues:

    $results = [];
    foreach ($users as $user) {
        $results[] = $manager->collect(UserPrototype::class, $user);
    }
    
  • Avoid Redundant Calls Reuse the ResponsePrototypeManager instance (e.g., as a singleton) to cache reflection data.

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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle