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

Doctrine Specification Laravel Package

happyr/doctrine-specification

Reusable Doctrine query Specifications for PHP. Replace messy repositories and huge QueryBuilder methods with small, composable, testable spec classes. Reduce duplication, avoid methods with many arguments, and extend queries cleanly as your app grows.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Modular Query Logic: Enables decomposition of complex repository queries into reusable, testable Specification classes, reducing technical debt in repositories with bloated QueryBuilder logic.
  • Domain-Driven Design (DDD) Alignment: Supports ubiquitous language by encapsulating business rules (e.g., AdvertsWeShouldClose) as first-class citizens, improving collaboration between devs and non-technical stakeholders.
  • Build vs. Buy: Buy for teams already using Doctrine ORM/Laravel (avoids reinventing query composition). Build only if needing custom ORM integrations or advanced features (e.g., real-time filtering).
  • Use Cases:
    • Search/Filtering: Dynamic query composition (e.g., admin dashboards with multi-criteria filters).
    • Validation: Pre-query validation of entities (e.g., "Is this user eligible for this feature?").
    • Legacy Refactoring: Clean up monolithic repositories by extracting specs into separate classes.
    • API Layer: Standardize query logic across microservices or monoliths.

When to Consider This Package

  • Adopt if:

    • Your Doctrine repositories have >5 methods with complex QueryBuilder logic or duplicate conditions.
    • You need highly reusable query fragments (e.g., "active users," "premium subscribers") across services.
    • Testing queries is a pain point (specs are easier to mock than QueryBuilder).
    • Your team uses DDD and wants to align query logic with domain models.
    • You’re on Symfony/Laravel with Doctrine ORM (v2.5+).
  • Look elsewhere if:

    • You’re using non-Doctrine ORMs (e.g., Eloquent, Propel).
    • Your queries are simple CRUD (no need for composition).
    • You prioritize raw performance over maintainability (specs add slight overhead).
    • Your team lacks PHP/OOP maturity (specs require discipline in design).
    • You need real-time filtering (consider Elasticsearch or database views).

How to Pitch It (Stakeholders)

For Executives:

"This library lets us write database queries like Lego blocks—reusable, testable, and aligned with business rules. Instead of copying/pasting messy QueryBuilder code across repositories, we’ll encapsulate logic (e.g., ‘active users,’ ‘expired subscriptions’) into clean, shareable classes. This reduces bugs, speeds up development, and makes it easier to add new filters (e.g., for admin dashboards). Think of it as moving from spaghetti queries to a structured, scalable system—saving time and money long-term."

ROI:

  • Dev Velocity: Faster to add/modify queries (no more QueryBuilder spaghetti).
  • Maintainability: 30–50% reduction in repository bloat (anecdotally reported by adopters).
  • Scalability: Supports complex filtering (e.g., multi-tenant apps) without procedural hacks.

For Engineers:

*"This implements the Specification pattern for Doctrine, solving three key problems:

  1. Bloated Repositories: Replace findActiveUsers(), findActiveUsersWithPhotos(), etc., with composable specs like ActiveUserSpec + HasPhotoSpec.
  2. Unittestable Queries: Mock specs easily (vs. QueryBuilder which requires DB connections).
  3. Reusable Logic: Build query trees (e.g., Spec::andX(new PremiumUser(), new ActiveThisMonth())) without procedural duplication.

Example:

// Before: Monolithic repository method
public function getActivePremiumUsers() {
    return $this->createQueryBuilder('u')
        ->where('u.active = 1')
        ->andWhere('u.subscription_end > :now')
        ->setParameter('now', new \DateTime())
        ->getQuery()
        ->getResult();
}

// After: Composable specs
$spec = Spec::andX(
    new ActiveUserSpec(),
    new PremiumSubscriptionSpec(new \DateTime())
);
return $this->repository->match($spec);

Tradeoffs:

  • Learning Curve: Requires adopting a new pattern (but pays off at scale).
  • Overhead: Minor performance cost (~5–10%) for complex queries (negligible for most apps).
  • Tooling: Works seamlessly with Symfony/Laravel Doctrine; no extra config needed.

Next Steps:

  1. Pilot: Refactor 1–2 complex repositories to specs.
  2. Standardize: Create a Spec namespace and naming conventions (e.g., *Spec.php).
  3. Integrate: Add specs to your API layer for dynamic filtering (e.g., /users?spec=active&spec=premium)."*
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle