Weave 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

App Registry Common Laravel Package

aeruz/app-registry-common

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require aeruz/app-registry-common
    

    Publish the package's configuration (if applicable) with:

    php artisan vendor:publish --provider="Aeruz\AppRegistryCommon\AppRegistryCommonServiceProvider"
    
  2. First Use Case: Defining a Registry Model Extend the base RegistryModel trait to create a custom registry entry:

    use Aeruz\AppRegistryCommon\Models\RegistryModel;
    
    class MyApp extends RegistryModel
    {
        protected $registryKey = 'my_app'; // Unique identifier for the registry
        protected $registryName = 'My Application'; // Human-readable name
    }
    
  3. Registering the Model Bind your model to the registry in a service provider:

    use Aeruz\AppRegistryCommon\Facades\AppRegistry;
    
    public function register()
    {
        AppRegistry::register(MyApp::class);
    }
    
  4. Retrieving Entries Fetch all registered apps or a specific one:

    $apps = AppRegistry::all();
    $myApp = AppRegistry::get('my_app');
    

Implementation Patterns

1. Model-Based Registry

  • Pattern: Use RegistryModel as a base for all registry entries.
    class Service extends RegistryModel
    {
        protected $registryKey = 'service_x';
        protected $registryName = 'Service X';
        protected $version = '1.0.0';
    }
    
  • Why? Ensures consistency in metadata (e.g., registryKey, registryName) and leverages built-in validation.

2. Dynamic Registration

  • Pattern: Register models dynamically (e.g., via discovery or config).
    // In a service provider or boot method
    AppRegistry::register(Service::class);
    AppRegistry::register(AnotherService::class);
    
  • Tip: Use AppRegistry::registerMultiple([Class1::class, Class2::class]) for bulk registration.

3. Dependency Injection

  • Pattern: Inject the registry facade or repository into controllers/services.
    use Aeruz\AppRegistryCommon\Facades\AppRegistry;
    
    class AppController extends Controller
    {
        public function showApps()
        {
            $apps = AppRegistry::all();
            return view('apps.index', compact('apps'));
        }
    }
    
  • Alternative: Bind the registry repository to the container for type-hinted DI:
    $this->app->bind(
        \Aeruz\AppRegistryCommon\Repositories\AppRegistryRepository::class,
        \Aeruz\AppRegistryCommon\Repositories\EloquentAppRegistryRepository::class
    );
    

4. Event-Driven Workflows

  • Pattern: Listen for registry events (e.g., Registered, Unregistered).
    use Aeruz\AppRegistryCommon\Events\RegistryEvent;
    
    Event::listen(RegistryEvent::REGISTERED, function ($event) {
        Log::info("Registered app: {$event->app->registryName}");
    });
    
  • Use Case: Trigger notifications, cache updates, or side effects when apps are registered/unregistered.

5. Validation and Rules

  • Pattern: Extend validation rules for custom registry logic.
    use Aeruz\AppRegistryCommon\Rules\RegistryKey;
    
    $validator = Validator::make($data, [
        'registry_key' => ['required', new RegistryKey],
    ]);
    
  • Tip: Override getRules() in your RegistryModel for model-specific validation.

6. API Integration

  • Pattern: Expose registry data via API resources.
    namespace App\Http\Resources;
    
    use Aeruz\AppRegistryCommon\Models\RegistryModel;
    use Illuminate\Http\Resources\Json\JsonResource;
    
    class AppResource extends JsonResource
    {
        public function toArray($request)
        {
            return [
                'key' => $this->registryKey,
                'name' => $this->registryName,
                'version' => $this->version ?? null,
            ];
        }
    }
    
  • Endpoint Example:
    Route::get('/apps', function () {
        return AppResource::collection(AppRegistry::all());
    });
    

Gotchas and Tips

Pitfalls

  1. Duplicate Registry Keys

    • Issue: Registering two models with the same registryKey will overwrite the first entry.
    • Fix: Validate uniqueness before registration or use a custom repository to enforce constraints.
      if (AppRegistry::has('duplicate_key')) {
          throw new \InvalidArgumentException("Key 'duplicate_key' already exists.");
      }
      
  2. Missing registryKey or registryName

    • Issue: The package expects these properties to be defined in RegistryModel subclasses. Omitting them may cause runtime errors.
    • Fix: Ensure all custom models include:
      protected $registryKey = '...';
      protected $registryName = '...';
      
  3. Repository Mismatch

    • Issue: Using the default repository (e.g., EloquentAppRegistryRepository) without setting up the database schema.
    • Fix: Publish and run migrations:
      php artisan vendor:publish --tag="app-registry-migrations"
      php artisan migrate
      
  4. Caching Stale Data

    • Issue: If using caching (e.g., CacheAppRegistryRepository), stale data may persist after updates.
    • Fix: Clear the cache manually or implement cache invalidation in event listeners:
      Event::listen(RegistryEvent::UPDATED, function () {
          Cache::forget('app_registry');
      });
      

Debugging Tips

  1. Enable Logging Configure the package to log registry operations:

    'logging' => [
        'enabled' => true,
        'channel' => 'single',
    ],
    

    in the published config.

  2. Inspect Registered Apps Dump the registry state for debugging:

    dd(AppRegistry::all()->toArray());
    
  3. Override Repository for Testing Mock the repository in tests to avoid database dependencies:

    $this->app->instance(
        \Aeruz\AppRegistryCommon\Repositories\AppRegistryRepository::class,
        Mockery::mock(\Aeruz\AppRegistryCommon\Repositories\AppRegistryRepository::class)
    );
    

Extension Points

  1. Custom Repository Implement your own repository (e.g., for Redis or a custom storage backend):

    use Aeruz\AppRegistryCommon\Repositories\AppRegistryRepository;
    
    class RedisAppRegistryRepository implements AppRegistryRepository
    {
        public function all(): Collection
        {
            return collect(Redis::hgetall('app_registry'));
        }
    
        // Implement other methods...
    }
    

    Bind it in a service provider:

    $this->app->bind(
        AppRegistryRepository::class,
        RedisAppRegistryRepository::class
    );
    
  2. Custom Events Extend the event system for domain-specific logic:

    Event::listen(RegistryEvent::REGISTERED, function ($event) {
        // Custom logic (e.g., notify a queue)
        Dispatch(new ProcessAppRegistration($event->app));
    });
    
  3. Model Observers Add observers to RegistryModel for automatic side effects:

    class AppRegisteredObserver
    {
        public function registered(RegistryModel $model)
        {
            // Example: Log to a custom table
            CustomLog::create(['action' => 'app_registered', 'key' => $model->registryKey]);
        }
    }
    

    Register the observer in a service provider:

    RegistryModel::observe(AppRegisteredObserver::class);
    
  4. API Middleware Restrict access to registry endpoints:

    Route::middleware(['auth:api', 'can:view,app'])->get('/apps', function () {
        return AppRegistry::all();
    });
    
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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin