# Laravel:ports And Adapters

> Use hexagonal architecture for external systems; define ports (interfaces) and per-provider adapters; select adapter at composition edge

- Skill: `jpcaparas/laravel-ports-and-adapters` (Agent Skill)
- Install (CLI): `npx skillmds@latest add jpcaparas/laravel-ports-and-adapters`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jpcaparas/laravel-ports-and-adapters/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: jpcaparas (https://skillmd.com/u/jpcaparas)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/jpcaparas/laravel-ports-and-adapters

---


# Ports and Adapters (Hexagonal)

Abstract integrations behind stable interfaces. Keep vendor SDKs out of your domain code.

## Shape

- Port: PHP interface that expresses only what the app needs
- Adapters: one per provider, wrapping SDK quirks
- Selection: choose adapter via config/env/service provider

## Example (email)

```php
// Port
interface MailPort {
    public function send(string $to, string $subject, string $html): void;
}

// Adapter
final class SesMailAdapter implements MailPort {
    public function __construct(private \Aws\Ses\SesClient $ses) {}
    public function send(string $to, string $subject, string $html): void {
        // wrap SES specifics here
    }
}

// Composition (AppServiceProvider)
$this->app->singleton(MailPort::class, function () {
    return match (config('mail.driver')) {
        'ses' => new SesMailAdapter(app('aws.ses')),
        default => new SmtpMailAdapter(/* ... */),
    };
});
```

## Tips

- Normalize SDK data into your own types/DTOs
- Expose only portable capabilities via the port
- Keep adapters thin and well-tested


