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

Contracts Laravel Package

symfony/contracts

Symfony Contracts provides small, domain-focused PHP interfaces, traits, and normative docblocks extracted from Symfony components. Use them as stable type hints for loose coupling, interoperability, and easy DI/autowiring with battle-tested implementations.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit Symfony Contracts provides a highly strategic fit for Laravel applications targeting decoupled, reusable, and framework-agnostic architecture. The package’s domain-specific interfaces (e.g., CacheInterface, EventDispatcherInterface, HttpClientInterface) align perfectly with Laravel’s service container and dependency injection patterns, enabling:

  • Infrastructure abstraction: Decouple caching, events, HTTP clients, and mailers from Laravel’s concrete implementations.
  • Cross-framework compatibility: Build reusable libraries that work seamlessly in Laravel, Symfony, or other PHP ecosystems.
  • Future-proofing: Prepare for potential migrations (e.g., Symfony integration) or third-party implementation swaps without rewriting business logic.
  • Testing and mocking: Simplify unit/integration tests by mocking contracts (e.g., CacheInterface) instead of Laravel’s concrete classes.

Integration feasibility Feasibility is moderate-to-high but requires explicit bridging due to Laravel’s lack of native contract implementations. Key considerations:

  1. Service container alignment: Laravel’s alias() and bind() methods can map contracts to concrete implementations (e.g., CacheInterfaceIlluminate\Cache\Repository).
  2. Version compatibility: Laravel 10+ (PHP 8.1+) works best with Symfony Contracts v3.x+; avoid v2.x due to PHP 8.0 incompatibilities.
  3. Implementation availability: Concrete implementations (e.g., symfony/cache, symfony/http-client) must be installed and configured separately.
  4. Autowiring limitations: Laravel’s autowiring ignores Symfony interfaces unless explicitly bound, risking Target class does not exist errors.

Technical risk

  • Version skew: Mismatches between Symfony Contracts (e.g., symfony/cache-contracts:3.x) and Laravel’s underlying implementations (e.g., symfony/cache:6.x) may introduce runtime errors or behavioral inconsistencies.
  • Semantic gaps: Contracts may define behaviors not covered by Laravel’s defaults (e.g., CacheInterface::get() retry policies or HttpClientInterface middleware). Custom adapters or extensions may be required.
  • Autowiring pitfalls: Without proper binding, autowiring fails silently, leading to runtime errors. Requires explicit configuration in AppServiceProvider.
  • Legacy code refactoring: Replacing Laravel-specific type hints (e.g., CacheManager) with contracts requires careful sequencing to avoid breaking changes in existing codebases.
  • Performance overhead: Contract-based dispatching (e.g., event listeners, HTTP clients) may introduce minor overhead compared to direct Laravel method calls, though this is typically negligible.

Key questions

  1. Implementation strategy: Will we use Symfony’s official implementations (e.g., symfony/cache, symfony/http-client) or third-party libraries (e.g., predis/predis, guzzlehttp/guzzle)?
  2. Migration scope: Which Laravel services will be prioritized for contract adoption (e.g., cache → events → HTTP clients → mailers)?
  3. Testing strategy: How will we ensure contract compliance of custom implementations (e.g., unit tests for CacheInterface retry logic or HttpClientInterface middleware)?
  4. Performance validation: Are there measurable overheads from contract-based dispatching vs. direct Laravel method calls, and how will we benchmark this?
  5. Team readiness: Does the team have experience with interface-based design, Laravel service container customization, and dependency injection patterns?
  6. Facade vs. DI: Will we replace Laravel facades (e.g., Cache::store()) with contract-based service calls in new development, and how will we handle legacy facade usage?
  7. Third-party compatibility: Are there existing third-party libraries in our stack that already implement Symfony Contracts, and how will we leverage them?
  8. Long-term roadmap: How does this integration align with potential future migrations (e.g., Symfony adoption) or vendor lock-in avoidance strategies?

Integration Approach

Stack fit Symfony Contracts is ideal for infrastructure-heavy layers where abstraction reduces vendor lock-in and improves reusability:

  • Cache layer: Replace Illuminate\Cache\Repository or CacheManager with Symfony\Contracts\Cache\CacheInterface.
  • Event system: Use Symfony\Contracts\EventDispatcher\EventDispatcherInterface alongside Laravel’s Dispatcher for cross-framework compatibility.
  • HTTP clients: Adopt Symfony\Contracts\HttpClient\HttpClientInterface to replace Guzzle or Illuminate\Http\Client for reusable HTTP logic.
  • Mailers/translation: Leverage Symfony\Contracts\Mailer\MailerInterface or TranslatorInterface for framework-agnostic email and localization.
  • Messenger/queues: Use Symfony\Contracts\Messenger\MessageBusInterface for queue-agnostic design (e.g., integrating with Symfony Messenger or Laravel Queues).
  • Logging: Adopt Symfony\Contracts\EventDispatcher\LoggerInterface for standardized logging contracts.

Migration path

  1. Assessment phase:

    • Audit Laravel services for framework-specific dependencies (e.g., Cache, Events, Http, Mail).
    • Identify non-critical services (e.g., logging cache, background jobs, third-party integrations) for pilot adoption.
    • Evaluate third-party libraries for existing contract support (e.g., predis/predis implements CacheInterface).
  2. Pilot implementation:

    • Install contracts and a concrete implementation:
      composer require symfony/contracts symfony/cache symfony/http-client symfony/event-dispatcher
      
    • Bind contracts to Laravel services in AppServiceProvider:
      $this->app->bind(
          Symfony\Contracts\Cache\CacheInterface::class,
          Symfony\Component\Cache\Adapter\AdapterInterface::class
      );
      $this->app->alias(
          Symfony\Contracts\Cache\CacheInterface::class,
          Illuminate\Cache\Repository::class
      );
      
    • Refactor a single service to type-hint CacheInterface instead of CacheManager or Repository.
    • Test the pilot with mock implementations (e.g., MockCache) to ensure compliance.
  3. Gradual rollout:

    • Expand to other domains (e.g., EventDispatcherInterface, HttpClientInterface).
    • Replace Laravel facades (e.g., Cache::store(), Http::get()) with contract-based service calls in new code.
    • Enforce dependency injection (not facades) for contract-injected services.
    • Use interfaces in constructors and avoid service locators (e.g., app()->make()).
  4. Legacy adaptation:

    • Create adapter classes to wrap Laravel-specific implementations (e.g., LaravelCacheAdapter implements CacheInterface).
    • Use traits (e.g., Symfony\Contracts\Cache\CacheItemInterface) for partial compliance in legacy code.
    • Gradually replace facade calls with injected services in existing codebases.
  5. Autowiring configuration:

    • Configure Laravel’s autowiring to recognize Symfony contracts by adding them to config/app.php:
      'providers' => [
          // ...
          Symfony\Contracts\Cache\CacheInterface::class => Symfony\Component\Cache\Adapter\AdapterInterface::class,
      ],
      
    • Alternatively, use autowiring aliases in config/autowire.php.

Compatibility

  • Laravel 10+: Full compatibility with Symfony Contracts v3.x (PHP 8.1+). Recommended for new projects.
  • Laravel 9.x: Limited to Symfony Contracts v2.x (PHP 8.0), with potential deprecation risks as Symfony moves to v3.x.
  • Third-party libraries: Prefer libraries that declare provide in composer.json (e.g., "symfony/cache-implementation": "1.0"). Examples:
    • symfony/cache (official implementation of CacheInterface).
    • predis/predis (Redis cache implementing CacheInterface).
    • guzzlehttp/guzzle (implements HttpClientInterface).
  • PSR overlap: Contracts extend PSRs (e.g., CacheInterface extends Psr\SimpleCache\CacheInterface) but add Symfony-specific features (e.g., tagging, retry policies).

Sequencing

  1. Infrastructure-first: Prioritize domains with the highest reuse potential (e.g., cache, HTTP clients, events).
  2. New development: Enforce contract usage in new services before touching legacy code to avoid technical debt.
  3. Facade replacement: Gradually replace facades (e.g., Cache::remember(), Http::post()) with injected services in new features.
  4. Testing: Validate contract compliance via mock implementations (e.g., MockCache, MockHttpClient) and integration tests with real implementations.
  5. Documentation: Update API docs to reflect contract-based interfaces (e.g., @param Symfony\Contracts\Cache\CacheInterface $cache).
  6. Performance benchmarking: Measure overhead of contract-based dispatching vs. direct Laravel calls in critical paths (e.g., high-traffic HTTP routes).
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi