Installation
composer require eventsauce/id-encoding
This auto-installs ramsey/uuid (v4.1+) as a dependency.
First Use Case: Encode/Decode UUIDs
use EventSauce\IdEncoding\IdEncoder;
use Ramsey\Uuid\Uuid;
$encoder = new IdEncoder();
$uuid = Uuid::uuid4();
// Encode UUID to URL-safe string (e.g., "a1b2c3d4-5678-90ef-ghij-klmnopqrstuv")
$encodedId = $encoder->encode($uuid);
// Decode back to UUID
$decodedUuid = $encoder->decode($encodedId);
Where to Look First
IdEncoder class: Core encoding/decoding logic in src/IdEncoder.php.tests/ for edge cases (e.g., malformed input).IdEncoderFactory for DI (e.g., Laravel service container).Eloquent Model Integration Add accessors/mutators to encode/decode IDs automatically:
// app/Models/Event.php
use EventSauce\IdEncoding\IdEncoder;
class Event extends Model {
public function getEncodedIdAttribute(): string {
return app(IdEncoder::class)->encode($this->id);
}
public function setEncodedIdAttribute(string $encodedId): void {
$this->id = app(IdEncoder::class)->decode($encodedId);
}
}
API Resource Transformation Use encoded IDs in API responses:
// app/Http/Resources/EventResource.php
public function toArray($request) {
return [
'id' => $this->whenLoaded('id', fn () => $this->encoded_id),
'title' => $this->title,
];
}
Service Container Binding
Register the encoder in AppServiceProvider:
public function register() {
$this->app->singleton(IdEncoder::class, function ($app) {
return new \EventSauce\IdEncoding\IdEncoder();
});
}
Event/Queue Payloads Encode IDs for event payloads or queue jobs:
// app/Events/OrderCreated.php
public function __construct(
public string $encodedOrderId,
public string $customerId
) {}
// Usage:
$encodedId = app(IdEncoder::class)->encode($order->id);
event(new OrderCreated($encodedId, $customerId));
Custom ID Types
Extend IdEncoder for non-UUID IDs (e.g., integers):
class IntegerIdEncoder extends \EventSauce\IdEncoding\IdEncoder {
public function encode($id): string {
return base64_encode((string) $id);
}
public function decode(string $encoded): int {
return (int) base64_decode($encoded);
}
}
Database Storage
Store encoded IDs in VARCHAR columns (e.g., encoded_id VARCHAR(22) for Base64 UUIDs):
// Migration
Schema::table('events', function (Blueprint $table) {
$table->string('encoded_id')->unique();
});
URL Generation Use encoded IDs in routes or redirects:
Route::get('/events/{encodedId}', [EventController::class, 'show']);
// Generate URL:
$url = route('events.show', ['encodedId' => $event->encoded_id]);
UUID Dependency
ramsey/uuid. If you’re not using UUIDs, avoid this package (use a custom encoder instead).composer.json for ramsey/uuid bloat if optimizing for size.Database Queries
// Wrong (compares string to UUID):
$events = Event::where('id', $encodedId)->get();
// Correct (decode first or use raw UUID):
$events = Event::where('id', app(IdEncoder::class)->decode($encodedId))->get();
Malformed Input
try {
$decoded = $encoder->decode($encodedId);
} catch (\InvalidArgumentException $e) {
abort(400, 'Invalid ID format');
}
Performance in Loops
$encodedIds = collect($events)->map(fn ($event) => cache()->remember(
"encoded_id_{$event->id}",
now()->addHours(1),
fn () => app(IdEncoder::class)->encode($event->id)
));
Log Raw vs. Encoded IDs Compare raw and encoded IDs during transitions:
\Log::debug('Raw ID', ['raw' => $event->id, 'encoded' => $event->encoded_id]);
Test Edge Cases
$this->assertEquals($uuid, $encoder->decode($encoder->encode($uuid)));
Check for Silent Failures
decode() throws exceptions for invalid input (default behavior).Default Encoding Scheme
class CustomEncoder extends IdEncoder {
public function encode($id): string {
return base32_encode($id); // Alternative scheme
}
}
Laravel Caching
$encodedId = cache()->remember(
"encoded_id_{$model->id}",
now()->addHours(1),
fn () => app(IdEncoder::class)->encode($model->id)
);
Migration Strategy
Custom Encoders
Extend IdEncoder for project-specific needs:
class ProjectIdEncoder extends IdEncoder {
public function encode($id): string {
return strtoupper(md5($id)); // Custom logic
}
}
Laravel Macros
Add helper methods to the IdEncoder facade:
IdEncoder::macro('encodeUuid', function ($uuid) {
return $this->encode($uuid);
});
EventSauce Integration If using EventSaucePHP/EventSauce, configure the encoder in the event store:
$eventStore = new \EventSauce\EventStore\EventStore(
new \EventSauce\EventStore\Persistence\MySql\MySqlEventRepository(
new \EventSauce\EventStore\Persistence\MySql\Connection($pdo),
new \EventSauce\EventStore\Persistence\MySql\Schema($pdo),
new \EventSauce\EventStore\Persistence\MySql\EventSerializer(
app(IdEncoder::class) // Inject encoder
)
)
);
Use Facades for Convenience Create a facade to simplify usage:
// app/Facades/IdEncoder.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class IdEncoder extends Facade {
protected static function getFacadeAccessor() {
return \EventSauce\IdEncoding\IdEncoder::class;
}
}
Now use IdEncoder::encode($id) globally.
Model Observers Automate encoding/decoding on save:
// app/Observers/EventObserver.php
class EventObserver {
public function saving(Event $event) {
if (!$event->encoded_id && $event->id) {
$
How can I help you explore Laravel packages today?