- How do I migrate from traditional Laravel controllers to Actions without breaking existing routes?
- Start by wrapping existing controller logic into an action class using `make:action`. Replace routes incrementally by pointing them to the action’s `asController()` method. The package provides a `Route::action()` helper for seamless integration. Legacy controllers can coexist until fully migrated.
- Can I use Laravel Actions with Inertia.js or Livewire for frontend frameworks?
- Yes. Actions integrate natively with Inertia by returning Inertia responses from the `asController()` method. For Livewire, you can dispatch actions as jobs or call them directly in component methods. Both workflows benefit from the same reusable business logic.
- What’s the performance impact of using Actions vs. native Laravel controllers/jobs?
- The overhead is minimal—benchmarks show negligible differences for typical use cases. Dynamic method dispatch (e.g., `asJob()`) uses reflection, but the package optimizes this with compiled classes and lazy loading. Hot paths (e.g., high-frequency actions) can be manually optimized if needed.
- How do I test an Action class that runs as both a controller and a job?
- Test the core `handle()` method in isolation using `Action::run()`. For context-specific tests (e.g., HTTP validation), mock dependencies and call `asController()` or `asJob()` directly. The `make:action` command generates test stubs to streamline this process.
- Does Laravel Actions support Laravel Nova for admin panels or custom tools?
- Absolutely. Actions power Nova tools or resource actions by returning Nova-specific responses from `asController()`. For example, create an action like `ApproveUserSubscription` and expose it via Nova’s tool routes. The package’s decorators handle Nova’s request/response lifecycle.
- How do I handle errors or exceptions in Actions, especially for queued jobs?
- Actions propagate exceptions by default, but you can customize error handling via the `jobFailed()` method for jobs or middleware for HTTP requests. For domain-specific errors, wrap exceptions in your `handle()` method. Job failures trigger Laravel’s queue failure system, which can be monitored via Horizon.
- Will Laravel Actions work with Laravel 10 or older versions?
- No, Laravel Actions requires Laravel 11–13 and PHP 8.2+. The package leverages modern PHP features like named arguments and enums, which aren’t backward-compatible. However, the architecture is designed for gradual adoption, so you can refactor legacy apps incrementally.
- Can I reuse an Action’s logic in multiple places without duplicating code?
- Yes, that’s the core benefit. Define the `handle()` method once, then expose it via `asController()`, `asJob()`, `asListener()`, etc. For example, a `SendWelcomeEmail` action can run synchronously (HTTP), asynchronously (queue), or on events (listener) using the same logic.
- How do I add custom validation or middleware to an Action?
- Use Laravel’s built-in validation (e.g., FormRequests) in `asController()` or decorators for jobs. For middleware, bind it to the action’s route or use the `withMiddleware()` decorator. The package provides hooks like `booting()` to inject custom logic before execution.
- Are there alternatives to Laravel Actions for organizing business logic?
- Alternatives include Laravel’s native controllers/jobs (but with more duplication), packages like `spatie/laravel-activitylog` for event-driven workflows, or domain-specific frameworks like `orchid/software`. However, Actions uniquely combine SRP, reusability, and multi-context execution in a single package without forcing a full architectural overhaul.