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

Simple Bus Query Bus Laravel Package

ajgl/simple-bus-query-bus

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • CQRS and DDD Alignment: The package excels in CQRS architectures by providing a dedicated query bus for read operations, cleanly separating them from command/write operations. This is ideal for Laravel applications adopting Domain-Driven Design (DDD) or hexagonal architecture, where queries are treated as first-class citizens with explicit handlers.
  • Middleware Extensibility: The package’s reliance on SimpleBus middleware allows for declarative cross-cutting concerns (e.g., caching, logging, validation) without modifying query handlers. This aligns with Laravel’s middleware pattern and reduces boilerplate.
  • Lazy Loading: The CallableMap and ServiceLocatorAwareCallableResolver enable on-demand handler resolution, reducing memory overhead for unused queries—a critical feature for Laravel apps with many potential but rarely used queries (e.g., analytics, reporting).
  • Query as Objects: Enforces explicit query design (e.g., FindUserByEmail) over ad-hoc SQL or repository calls, improving testability and collaboration (queries become self-documenting).

Technical Risk

  • Learning Curve: Requires familiarity with message buses, resolvers, and middleware patterns, which may be unfamiliar to Laravel teams accustomed to Eloquent or repositories. Mitigation: Provide internal workshops or code samples tailored to Laravel’s service container.
  • Synchronous Only: Not suitable for async/real-time queries (e.g., WebSocket updates). Mitigation: Pair with Laravel’s queue system for async commands; use this package only for synchronous reads.
  • Limited Community: Low GitHub stars (5) and no dependents may indicate stability risks. Mitigation:
    • Fork and maintain if critical (MIT license permits this).
    • Benchmark against direct Eloquent calls to validate performance.
    • Add tests for Laravel-specific integrations (e.g., service container binding).
  • No Built-in Caching: Unlike Laravel’s Cache facade, the package lacks native caching middleware. Mitigation: Implement a custom middleware (e.g., CacheQueryResultMiddleware) using Laravel’s cache drivers.
  • Query Naming Complexity: Requires consistent naming strategies (e.g., ClassBasedNameResolver vs. NamedMessage). Mitigation: Enforce a naming convention (e.g., Query suffix) in team guidelines.

Key Questions

  1. Performance Impact:
    • How does the query bus’s overhead compare to direct Eloquent calls or repository patterns for our most critical queries?
    • Can we micro-benchmark handler resolution vs. Laravel’s service container?
  2. Adoption Strategy:
    • Should we pilot this for complex queries (e.g., analytics, search) before full adoption?
    • How will we migrate existing ad-hoc queries (e.g., User::where()->get()) to the bus?
  3. Middleware Strategy:
    • Which cross-cutting concerns (caching, logging, validation) should we implement as middleware first?
    • How will we test middleware interactions (e.g., caching + validation order)?
  4. Tooling Integration:
    • Can we generate query classes (e.g., via Laravel IDE Helper or custom scripts) to reduce boilerplate?
    • How will this integrate with Laravel’s DTOs or API resources for consistent responses?
  5. Long-Term Maintenance:
    • Should we fork the package to add Laravel-specific features (e.g., cache middleware)?
    • How will we handle breaking changes in SimpleBus (this package’s dependency)?

Integration Approach

Stack Fit

  • Laravel Service Container: The package’s ServiceLocatorAwareCallableResolver integrates seamlessly with Laravel’s IoC container. Query handlers can be registered as services (e.g., app:bind) and resolved dynamically.
  • Middleware Integration: Laravel’s middleware pipeline can wrap the query bus to add global concerns (e.g., auth, rate-limiting) before queries reach handlers.
  • Event System: Query execution can dispatch events (e.g., QueryHandled) via Laravel’s event system for observability or side effects.
  • Testing: Laravel’s mocking tools (e.g., Mockery) can easily stub the query bus and its middleware for unit/integration tests.

Migration Path

  1. Phase 1: Pilot with Complex Queries
    • Select 2–3 high-complexity queries (e.g., dashboard metrics, search) and refactor them to use the query bus.
    • Example migration:
      // Before (ad-hoc)
      $users = User::where('active', true)->with('orders')->get();
      
      // After (query bus)
      $query = new FindActiveUsersWithOrders();
      $users = $queryBus->handle($query, $result);
      
  2. Phase 2: Standardize Query Objects
    • Enforce query objects for all new read operations. Use Laravel IDE Helper to generate stubs.
    • Example:
      class FindActiveUsersWithOrders implements NamedMessage {
          public static function messageName(): string { return 'find_active_users_with_orders'; }
      }
      
  3. Phase 3: Add Middleware
    • Implement caching middleware (e.g., Redis) for frequently used queries.
    • Example:
      $queryBus->appendMiddleware(new CacheQueryResultMiddleware(
          Cache::store('redis'),
          60 // TTL in seconds
      ));
      
  4. Phase 4: Deprecate Ad-Hoc Queries
    • Gradually replace direct Eloquent calls in controllers with query bus invocations.
    • Use Laravel’s deprecated attribute to flag old patterns for removal.

Compatibility

  • SimpleBus Dependency: The package depends on simple-bus/message-bus (v2.x). Ensure version compatibility with Laravel’s PHP version (8.0+).
  • Query Handler Types: Supports:
    • Closures (for simple logic).
    • Service-bound callables (for dependency-injected handlers).
    • Objects with handle() (for DDD-style handlers).
  • Laravel-Specific Quirks:
    • Service Container Binding: Query handlers can be Laravel services (e.g., App\Services\FindUserHandler).
    • Eloquent Integration: Handlers can use Eloquent models directly or via repositories.
    • Validation: Leverage Laravel’s Form Requests or Validator in middleware.

Sequencing

  1. Prerequisites:
    • Install simple-bus/message-bus and ajgl/simple-bus-query-bus.
    • Configure Laravel’s service container to resolve query handlers.
  2. Core Setup:
    • Define CatchReturnMessageBusSupportingMiddleware and DelegatesToMessageHandlerAndCatchReturnMiddleware.
    • Register query handlers in the CallableMap.
  3. Query Naming:
    • Choose a MessageNameResolver (e.g., ClassBasedNameResolver).
  4. Middleware Layer:
    • Add logging, caching, or validation middleware to the bus.
  5. Controller Integration:
    • Replace ad-hoc queries with $queryBus->handle($query, $result).
  6. Testing:
    • Write unit tests for query handlers and middleware.
    • Test integration with Laravel’s service container.

Operational Impact

Maintenance

  • Handler Updates: Changes to query logic require updating the handler class (not middleware or bus). This follows single responsibility and reduces merge conflicts.
  • Middleware Management: Cross-cutting concerns (e.g., caching) are isolated in middleware, making them easier to update or replace.
  • Dependency Updates: Monitor SimpleBus for breaking changes. The package’s MIT license allows forks if needed.
  • Query Registry: Maintain a centralized list of queries (e.g., in a Queries directory) to track all read operations.

Support

  • Debugging:
    • Use Laravel’s exception handling to catch and log query bus errors.
    • Add middleware for query tracing (e.g., log query names and execution time).
  • Performance Profiling:
    • Identify slow queries via middleware (e.g., BenchmarkQueryMiddleware).
    • Compare query bus overhead vs. direct Eloquent calls.
  • Common Issues:
    • Handler Not Found: Ensure query names match the CallableMap.
    • Middleware Order: Test middleware interactions (e.g., caching before validation).
    • Circular Dependencies: Avoid circular references in handler resolution.

Scaling

  • Horizontal Scaling:
    • The query bus is stateless (assuming handlers are stateless), making it horizontally scalable in distributed Laravel apps.
    • Use Laravel Horizon or queue workers for async command handling (separate from queries).
  • Caching Strategy:
    • Implement Redis caching middleware for high-frequency queries.
    • Use Laravel’s cache tags to invalidate cached queries when related 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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky