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

draw/contracts

Lightweight PHP contracts for Draw packages. Provides shared interfaces and abstractions to standardize implementations across components, improving interoperability, testing, and decoupling in Laravel or framework-agnostic projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require draw/contracts
    

    No publisher or service provider is required—this is a pure abstraction layer.

  2. First Use Case: Defining a Contract Use the Contract trait to define a formal interface for your domain logic:

    use Draw\Contracts\Contract;
    
    class UserContract implements Contract
    {
        public function validate(array $data): bool
        {
            // Validation logic
        }
    }
    
  3. Where to Look First

    • src/Contract.php: Core trait defining the Contract interface.
    • src/Exceptions/: Custom exceptions for contract violations.
    • tests/: Example implementations and edge cases.

Implementation Patterns

Core Workflow: Enforcing Contracts

  1. Define Contracts Extend Contract to enforce rules on data, services, or behaviors:

    class PaymentContract implements Contract
    {
        public function validate(array $data): bool
        {
            return !empty($data['amount']) && is_numeric($data['amount']);
        }
    }
    
  2. Integrate with Laravel Use contracts in service providers, form requests, or domain services:

    class PaymentService
    {
        public function process(PaymentContract $contract, array $data)
        {
            if (!$contract->validate($data)) {
                throw new \InvalidArgumentException('Invalid payment data');
            }
            // Process payment...
        }
    }
    
  3. Dependency Injection Bind contracts to interfaces in AppServiceProvider:

    $this->app->bind(
        PaymentContract::class,
        function ($app) {
            return new PaymentContract();
        }
    );
    
  4. Validation Layer Combine with Laravel’s validation:

    use Illuminate\Support\Facades\Validator;
    
    $validator = Validator::make($request->all(), [
        'amount' => 'required|numeric',
    ]);
    
    if ($validator->fails()) {
        throw new \Draw\Contracts\Exceptions\ContractValidationException(
            $validator->errors()
        );
    }
    

Gotchas and Tips

Pitfalls

  1. No Built-in Enforcement The package provides abstractions only—you must manually validate contracts. Example:

    // ❌ Won't auto-validate
    $service->process(new PaymentContract(), $data);
    
  2. Overhead for Simple Cases Avoid over-engineering for trivial validations. Use Laravel’s built-in validation when possible.

  3. Exception Handling Custom exceptions (ContractValidationException) are thrown but require manual catching:

    try {
        $service->process($contract, $data);
    } catch (\Draw\Contracts\Exceptions\ContractValidationException $e) {
        // Handle gracefully
    }
    

Tips

  1. Compose Contracts Chain multiple contracts for complex logic:

    class CompositeContract implements Contract
    {
        private $contracts;
    
        public function __construct(Contract ...$contracts)
        {
            $this->contracts = $contracts;
        }
    
        public function validate(array $data): bool
        {
            return collect($this->contracts)
                ->every(fn ($contract) => $contract->validate($data));
        }
    }
    
  2. Testing Strategies Mock contracts in unit tests:

    $mockContract = $this->createMock(Contract::class);
    $mockContract->method('validate')->willReturn(true);
    
  3. Extending the Package

    • Add custom exceptions by extending \Draw\Contracts\Exceptions\ContractException.
    • Override default behavior by implementing Contract methods in child classes.
  4. Performance Note For high-throughput systems, cache contract validation results if data is static:

    private $cache = [];
    
    public function validate(array $data): bool
    {
        $key = md5(serialize($data));
        return $this->cache[$key] ??= parent::validate($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