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

Attribute Execution Bundle Laravel Package

arnaud-23/attribute-execution-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation: Add the bundle via Composer:

    composer require arnaud-23/attribute-execution-bundle
    

    Ensure symfony/security-bundle is installed if using the Security attribute.

  2. First Use Case: Apply attributes to a service method to enable middleware behavior:

    use Arnaud23\AttributeExecutionBundle\Attribute\Cache;
    
    class UserService {
        #[Cache] // Applies caching with default strategy (array) and TTL (300s)
        public function getUserData(int $id): array {
            return ['id' => $id, 'name' => 'John Doe'];
        }
    }
    
  3. Verify Setup: Call the method and observe the behavior (e.g., cached responses).

Where to Look First

  • Attributes: Focus on the three core attributes (Security, Cache, Transactional) in src/Attribute/.
  • Configuration: Check config/packages/attribute_execution.yaml for cache/strategy overrides.
  • Middleware: Explore src/Middleware/ for built-in logic (e.g., SecurityMiddleware, CacheMiddleware).

Implementation Patterns

Usage Patterns

  1. Attribute Placement:

    • Class-level: Applies to all methods (e.g., @Transactional on a UserRepository class).
    • Method-level: Overrides class-level attributes (e.g., @Cache(ttl: 60) on a specific method).
  2. Middleware Chaining: Combine attributes for layered behavior:

    #[Security('ROLE_ADMIN')]
    #[Cache(strategy: 'redis', ttl: 3600)]
    public function sensitiveData(): array { ... }
    

    Execution order: Security → Cache → Method logic.

  3. Custom Strategies: Extend the CacheStrategyInterface to add new cache backends (e.g., MemcachedStrategy).

  4. Dependency Injection: Services using attributes are auto-configured. No manual proxy setup is needed.

Workflows

  1. Caching Workflow:

    • Write: Cache invalidation is automatic (TTL-based).
    • Read: Check cache before executing logic.
    • Fallback: Execute method if cache miss occurs.
  2. Security Workflow:

    • Pre-flight: Validate user roles before method execution.
    • Exception: Throw AccessDeniedException if unauthorized.
  3. Transactional Workflow:

    • Scope: Wrap method in a database transaction.
    • Rollback: Auto-rollback on exceptions.

Integration Tips

  • Symfony Controllers: Use attributes on controller actions to enforce security/caching:

    #[Security('ROLE_USER')]
    #[Cache(ttl: 1800)]
    public function dashboard(): Response { ... }
    
  • Doctrine Repositories: Apply @Transactional to repository methods for atomic operations:

    #[Transactional('default')]
    public function transferFunds(User $from, User $to, float $amount): void { ... }
    
  • Event Listeners: Decorate listeners with @Cache to avoid redundant processing:

    #[Cache(strategy: 'redis', ttl: 300)]
    public function onUserCreated(UserCreatedEvent $event): void { ... }
    
  • Testing: Mock middleware in tests using the bundle’s AttributeExecutionContext:

    $context = new AttributeExecutionContext($service);
    $context->execute([new CacheAttribute()]);
    

Gotchas and Tips

Pitfalls

  1. Attribute Conflicts:

    • Class vs. Method: Method-level attributes override class-level ones. Unexpected behavior may occur if not intentional.
    • Order Dependency: Middleware executes in declaration order (top-to-bottom). Reorder attributes for desired precedence.
  2. Cache Invalidation:

    • TTL-based caches may stale data unexpectedly. Use explicit invalidation (e.g., Cache::forget()) for critical data.
  3. Security Shortcuts:

    • Avoid overusing @Security on public APIs. Validate input early to fail fast.
  4. Transaction Boundaries:

    • Long-running methods may hit database timeouts. Break into smaller transactions or use @Transactional selectively.
  5. Configuration Overrides:

    • Cache strategies in attribute_execution.yaml must match attribute names (case-sensitive).

Debugging

  1. Middleware Logs: Enable debug mode to log middleware execution:

    attribute_execution:
        debug: true
    
  2. Attribute Introspection: Use reflection to inspect applied attributes:

    $reflection = new ReflectionMethod(UserService::class, 'getUserData');
    $attributes = $reflection->getAttributes(Cache::class);
    
  3. Cache Debugging: Check cache hits/misses with:

    $cache = $this->container->get('attribute_execution.cache.array');
    $cache->getStats(); // Returns hit/miss counts.
    

Tips

  1. Performance Tuning:

    • Use redis strategy for high-throughput caching (lower latency than array).
    • Adjust TTLs based on data volatility (e.g., 60s for real-time data, 3600s for static content).
  2. Custom Middleware: Extend AbstractMiddleware to create reusable logic:

    class LogExecutionMiddleware extends AbstractMiddleware {
        public function process(ExecutionContext $context): mixed {
            Log::info('Executing ' . $context->getMethod());
            return $context->next($context);
        }
    }
    

    Register it in config/packages/attribute_execution.yaml:

    attribute_execution:
        middleware:
            log: App\Middleware\LogExecutionMiddleware
    
  3. Attribute Composition: Combine attributes dynamically via dependency injection:

    public function __construct(
        private readonly CacheAttributeFactory $cacheFactory,
        private readonly SecurityAttributeFactory $securityFactory
    ) {}
    
    public function buildAttributes(): array {
        return [
            $this->securityFactory->create('ROLE_ADMIN'),
            $this->cacheFactory->create('redis', 3600),
        ];
    }
    
  4. Symfony Messenger: Use @Cache on message handlers to avoid duplicate processing:

    #[Cache(ttl: 900)]
    #[Asynchronous]
    public function __invoke(ProcessPaymentMessage $message): void { ... }
    
  5. Attribute Validation: Validate attributes at runtime using Symfony’s validator:

    use Symfony\Component\Validator\Constraints as Assert;
    
    #[Security(roles: ['ROLE_ADMIN'])]
    #[Assert\Expression(
        "value === 'admin'",
        message: "Invalid role specified."
    )]
    public function secureMethod(): void { ... }
    
  6. Testing Attributes: Mock the AttributeExecutionContext in unit tests:

    $context = $this->createMock(ExecutionContext::class);
    $context->method('next')->willReturn('mocked_result');
    $this->service->executeWithContext($context);
    
  7. Attribute Inheritance: Use traits to share attribute configurations across services:

    trait CachedTrait {
        #[Cache(strategy: 'redis', ttl: 3600)]
        public function cachedMethod(): void { ... }
    }
    
  8. Fallback Logic: Handle middleware failures gracefully:

    #[Security('ROLE_ADMIN', fallback: true)] // Returns null instead of throwing
    public function adminOnly(): ?array { ... }
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
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