Laravel Pennant is a powerful and lightweight feature flag package introduced in Laravel 10. It allows developers to easily implement feature toggles, enabling incremental rollouts, A/B testing, and more flexible development strategies. In this post, we'll explore how to use Pennant and showcase some practical examples.
Getting Started with Laravel Pennant
First, let's install Pennant:
composer require laravel/pennant
php artisan vendor:publish --provider="Laravel\Pennant\PennantServiceProvider"
php artisan migrate
Defining Features
There are two main ways to define features in Pennant:
Using the Feature Facade
In your AppServiceProvider
:
use Laravel\Pennant\Feature;
use App\Models\User;
public function boot()
{
Feature::define('new-dashboard', function (User $user) {
return $user->isAdmin() || $user->created_at->isAfter(now()->subDays(30));
});
}
Using Class-Based Features
Create a new feature class:
php artisan pennant:feature NewDashboard
Then define the logic in the class:
namespace App\Features;
use App\Models\User;
class NewDashboard
{
public function resolve(User $user): bool
{
return $user->isAdmin() || $user->created_at->isAfter(now()->subDays(30));
}
}
Checking Features
You can check if a feature is active in several ways:
// In controllers or other parts of your application
if (Feature::active('new-dashboard')) {
// Show new dashboard
}
// For class-based features
if (Feature::active(NewDashboard::class)) {
// Show new dashboard
}
// In Blade templates
@feature('new-dashboard')
<x-new-dashboard />
@else
<x-old-dashboard />
@endfeature
Suggested Usages
Gradual Feature Rollout
Roll out a new feature to a percentage of users:
Feature::define('new-chat', function (User $user) { return $user->id % 100 < 25; // 25% of users });
A/B Testing
Implement A/B testing for a new UI design:
Feature::define('new-ui', function (User $user) { return $user->id % 2 === 0; // 50% of users see new UI });
Beta Testing Program
Allow certain users to access beta features:
Feature::define('beta-feature', function (User $user) { return $user->isBetaTester(); });
Geographic Feature Availability
Enable features based on user location:
Feature::define('eu-compliance', function (User $user) { return $user->country->isInEU(); });
Feature Toggles in API
Use feature flags to version your API:
Route::middleware('auth:api')->group(function () { Route::get('/data', function (Request $request) { if (Feature::active('new-api-version')) { return $this->newApiResponse(); } return $this->legacyApiResponse(); }); });
Best Practices
Use Descriptive Names: Choose clear, descriptive names for your features to make them easily understandable.
Keep Logic Simple: Try to keep the feature resolution logic simple and focused.
Leverage Scopes: Use Pennant's scoping capabilities to check features for specific models or entities.
Clean Up Unused Flags: Regularly review and remove feature flags that are no longer needed.
Test Both States: Always test your application with the feature both active and inactive.
Laravel Pennant provides a clean and efficient way to implement feature flags in your Laravel applications. By leveraging its capabilities, you can achieve more flexible, controlled, and testable feature releases. Whether you're implementing gradual rollouts, conducting A/B tests, or managing complex feature sets, Pennant offers the tools to make your development process smoother and more robust.
Remember, feature flags are powerful tools, but they should be used judiciously. Over-reliance on feature flags can lead to complex codebases, so always consider the long-term implications of each flag you introduce.