dragon-code/contracts
Dragon Code Contracts provides a lightweight set of PHP interfaces (contracts) you can reuse across any project to standardize key behaviors, improve type-safety, and keep implementations decoupled. Ideal as a shared dependency for packages and applications.
Installation:
composer require dragon-code/contracts
Add to composer.json under require-dev if only for testing.
First Use Case:
Implement a Dtoable contract for a data transfer object:
use DragonCode\Contracts\Dto\Dtoable;
class UserDto implements Dtoable
{
public function toArray(): array
{
return [
'name' => $this->name,
'email' => $this->email,
];
}
}
Where to Look First:
ShouldQueue for Laravel 11/12).DTOs:
Use Dtoable for consistent serialization across APIs:
class ApiResponse implements Dtoable
{
public function toArray(): array
{
return ['data' => $this->data, 'status' => $this->status];
}
}
Pair with dragon-code/helpers for advanced features like JSON serialization.
Caching:
Extend Laravel’s cache with Cache\Store or Cache\Ttl:
use DragonCode\Contracts\Cache\Store;
class RedisCache implements Store
{
public function rememberForever(string $key, Closure $callback): mixed
{
return Cache::rememberForever($key, $callback);
}
}
Queues:
Enforce job deduplication with ShouldQueue or ShouldBeUnique:
use DragonCode\Contracts\Queue\ShouldQueue;
class ProcessPayment implements ShouldQueue
{
public function handle(): void
{
// Job logic
}
}
HTTP Clients:
Standardize domain handling with Http\Builder:
use DragonCode\Contracts\Http\Builder;
class ApiClient implements Builder
{
public function getBaseDomain(): string
{
return config('services.api.base_url');
}
}
Dependency Injection:
Bind contracts to implementations in AppServiceProvider:
$this->app->bind(
DragonCode\Contracts\Cache\Store::class,
DragonCode\Contracts\Cache\RedisCache::class
);
Testing: Mock contracts for isolated tests:
$mockCache = Mockery::mock(DragonCode\Contracts\Cache\Store::class);
$mockCache->shouldReceive('get')->andReturn('value');
Modular Monoliths:
Use contracts to define module boundaries (e.g., DragonCode\Contracts\Queue\ShouldQueue for cross-module jobs).
Laravel Facades: Extend existing facades to support contracts:
class CacheFacade extends Illuminate\Support\Facades\Cache
{
public static function rememberForever(string $key, Closure $callback): mixed
{
return app(DragonCode\Contracts\Cache\Store::class)->rememberForever($key, $callback);
}
}
Service Providers: Register contracts as aliases for framework services:
$this->app->alias(
DragonCode\Contracts\Cache\Store::class,
Illuminate\Contracts\Cache\Store::class
);
Laravel 11/12:
Leverage ShouldQueue for job batching or Dtoable with API resources.
Laravel Version Mismatches:
ShouldQueue requires Laravel 11+).symfony/http-kernel 7.0+).Over-Engineering:
Dtoable for a single-use DTO).Illuminate\Contracts\Cache\Store) when contracts add no value.Testing Quirks:
$this->app->instance(DragonCode\Contracts\Cache\Store::class, $mockCache);
Namespace Collisions:
\DragonCode\Contracts\Dto\Dtoable) to avoid conflicts with custom interfaces.Undefined Method Errors:
Verify implementations match the contract’s methods (e.g., toArray() for Dtoable).
php artisan ide-helper:generate # Generate stubs for IDE autocompletion
Cache Contracts:
If rememberForever fails, ensure the underlying cache driver supports it (e.g., Redis, file cache).
Queue Contracts:
For ShouldBeUnique, check if the queue driver supports deduplication (e.g., database queues).
IDE Support:
Use PHPStorm’s "Implement Methods" (Ctrl+I) to auto-generate contract methods.
Custom Contracts: Extend existing contracts for project-specific needs:
namespace App\Contracts;
use DragonCode\Contracts\Dto\Dtoable;
interface ExtendedDtoable extends Dtoable
{
public function toJson(): string;
}
Performance:
Dtoable with dragon-code/helpers for optimized serialization.Documentation:
/**
* @return array<string, mixed> Serialized data
*/
public function toArray(): array
{
return [...];
}
Migration Contracts:
Use DragonCode\Contracts\Database\MigrateDb for custom migration logic:
class CustomMigration implements MigrateDb
{
public function up(): void
{
// Custom migration logic
}
}
HTTP Domain Handling:
For multi-tenant apps, implement getDomainLevel() to extract subdomains:
public function getDomainLevel(): int
{
return 2; // e.g., "tenant.example.com" → "tenant"
}
How can I help you explore Laravel packages today?