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

dragon-code/contracts

Dragon Code Contracts provides a lightweight set of PHP interfaces (contracts) you can reuse across projects and packages. Use it to standardize common behaviors and keep implementations decoupled and consistent throughout your codebase.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require dragon-code/contracts
    
  2. First use case: Implement a Dtoable contract for a Data Transfer Object (DTO).
    use TheDragonCode\Contracts\Dto\Dtoable;
    
    class UserDto implements Dtoable
    {
        public function toArray(): array
        {
            return [
                'id' => $this->id,
                'name' => $this->name,
            ];
        }
    }
    
  3. Key files to explore:
    • vendor/the-dragon-code/contracts/src/ for all available contracts.
    • Focus on Dto, Cache, Queue, and Http namespaces for Laravel-specific patterns.

Implementation Patterns

Core Workflows

1. DTOs with Dtoable

  • Pattern: Use Dtoable for consistent serialization across APIs or services.
  • Example:
    use TheDragonCode\Contracts\Dto\Dtoable;
    
    class ApiResponseDto implements Dtoable
    {
        public function toArray(): array
        {
            return [
                'success' => true,
                'data' => $this->data->toArray(),
            ];
        }
    }
    
  • Integration Tip: Pair with dragon-code/helpers for advanced serialization (e.g., nested DTOs).

2. Caching with Cache\Store

  • Pattern: Standardize cache operations across services.
  • Example:
    use TheDragonCode\Contracts\Cache\Store;
    
    class RedisCache implements Store
    {
        public function get(string $key, $default = null): mixed
        {
            return cache()->get($key, $default);
        }
    
        public function rememberForever(string $key, callable $callback): mixed
        {
            return cache()->rememberForever($key, $callback);
        }
    }
    
  • Workflow: Inject Store into services instead of Laravel’s Illuminate\Contracts\Cache\Store.

3. Queue Jobs with ShouldQueue and ShouldBeUnique

  • Pattern: Enforce job deduplication and queuing.
  • Example:
    use TheDragonCode\Contracts\Queue\ShouldQueue;
    use TheDragonCode\Contracts\Queue\ShouldBeUnique;
    
    class ProcessPaymentJob implements ShouldQueue, ShouldBeUnique
    {
        public function handle(): void
        {
            // Job logic
        }
    
        public function uniqueFor(): string
        {
            return $this->paymentId;
        }
    }
    
  • Integration Tip: Use with Laravel’s dispatch() or dispatchSync() for consistency.

4. HTTP Requests with Http\Builder

  • Pattern: Standardize API request construction.
  • Example:
    use TheDragonCode\Contracts\Http\Builder;
    
    class ApiClient implements Builder
    {
        public function get(string $uri, array $query = []): array
        {
            return Http::get($uri, $query)->json();
        }
    
        public function getBaseDomain(): string
        {
            return config('services.api.base_url');
        }
    }
    

5. Database Migrations with Migrate\Contract

  • Pattern: Define migration interfaces for reusable schema logic.
  • Example:
    use TheDragonCode\Contracts\Migrate\Contract;
    
    class CreateUsersTable implements Contract
    {
        public function up(): void
        {
            Schema::create('users', function (Blueprint $table) {
                $table->id();
                $table->string('name');
            });
        }
    }
    

Dependency Injection

  • Laravel Service Providers: Bind contracts to implementations in register():
    $this->app->bind(
        TheDragonCode\Contracts\Cache\Store::class,
        App\Services\RedisCache::class
    );
    
  • Constructor Injection: Prefer dependency injection over static calls:
    class UserService
    {
        public function __construct(
            private Store $cache,
            private Builder $httpClient
        ) {}
    }
    

Gotchas and Tips

Pitfalls

  1. Laravel Version Mismatches:

    • The package drops support for Laravel <11. Ensure your laravel/framework version matches the package’s release notes.
    • Fix: Pin dragon-code/contracts to a compatible version (e.g., ^2.24.0 for Laravel 12).
  2. Overriding Laravel’s Built-in Contracts:

    • Avoid redefining interfaces already in Laravel (e.g., Illuminate\Contracts\Cache\Store). Use TheDragonCode\Contracts\Cache\Store for extended functionality (e.g., rememberForever).
    • Tip: Prefix custom contracts with your namespace to avoid collisions.
  3. Mocking in Tests:

    • Some contracts (e.g., ShouldQueue) rely on Laravel’s queue system. Mock interfaces carefully:
      $mockCache = Mockery::mock(TheDragonCode\Contracts\Cache\Store::class);
      $mockCache->shouldReceive('get')->andReturn('cached_value');
      
    • Gotcha: Laravel’s ShouldQueue trait conflicts with the ShouldQueue interface. Use the interface for testing.
  4. Symfony Dependency Conflicts:

    • The package uses Symfony components (e.g., symfony/http-kernel). Ensure your composer.json aligns with the package’s dependencies.
    • Fix: Run composer update after installation to resolve version conflicts.

Debugging Tips

  1. Interface Not Found:

    • Verify the namespace is correct (e.g., use TheDragonCode\Contracts\Dto\Dtoable).
    • Debug: Run composer dump-autoload if the interface isn’t recognized.
  2. Method Not Implemented:

    • Check the contract source for required methods (e.g., Dtoable::toArray() must return array).
    • Tip: Use PHPStorm’s "Implement Methods" refactor (⌘+⇧+I) to auto-generate stubs.
  3. Queue Job Deduplication Fails:

    • Ensure ShouldBeUnique::uniqueFor() returns a consistent string (e.g., userId-paymentType).
    • Debug: Log the uniqueFor() value to verify uniqueness.

Extension Points

  1. Custom Contracts:

    • Extend existing contracts for project-specific needs:
      namespace App\Contracts;
      
      use TheDragonCode\Contracts\Dto\Dtoable;
      
      interface ExtendedDtoable extends Dtoable
      {
          public function toJson(): string;
      }
      
  2. Laravel Facades:

    • Create facades for contracts to maintain Laravel-like syntax:
      Facades\Cache::get('key'); // Uses TheDragonCode\Contracts\Cache\Store
      
    • Example: Extend Laravel’s Cache facade to use the contract:
      Cache::shouldUseContractStore(true);
      
  3. Dynamic Method Binding:

    • Use Laravel’s Macroable trait to add dynamic methods to contract implementations:
      class CustomCache implements Store
      {
          use \Illuminate\Contracts\Macroable;
      
          public function __construct()
          {
              $this->macro('rememberDays', function ($key, $days, $callback) {
                  return $this->remember($key, $days * 24 * 60, $callback);
              });
          }
      }
      

Performance Notes

  • No Runtime Overhead: Contracts are pure interfaces with zero runtime cost.
  • Caching: The Cache\Store contract’s rememberForever method is optimized for Laravel’s cache drivers (e.g., Redis, database).
  • Queue Jobs: ShouldBeUnique adds minimal overhead (~1ms per job) for deduplication checks.

Configuration Quirks

  1. Cache Driver Defaults:
    • The package assumes Laravel’s cache configuration. Override defaults in config/cache.php if needed:
      'default' => env('CACHE_DRIVER', 'dragon'), // Custom driver
      
  2. Queue Connections:
    • For ShouldQueue, specify the queue connection in the job’s connection property:
      class ProcessPaymentJob implements ShouldQueue
      {
          public $connection = 'redis';
      }
      
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle