Summary
Resend is a modern email API service gaining significant traction among developers (4.6M+ installs of the PHP SDK). It offers a clean REST API, first-party PHP SDK (resend/resend-php), and a developer-friendly experience similar to SendGrid and Mailgun.
The Quantum Mailer package currently supports five adapters: SMTP, Mailgun, Mandrill, SendGrid, and Sendinblue. This task adds a sixth adapter -- ResendAdapter -- following the established HTTP-based adapter pattern used by the existing adapters.
Current Architecture
The mailer adapter pattern consists of:
| Component |
Path |
Role |
MailerInterface |
src/Mailer/Contracts/MailerInterface.php |
Contract all adapters implement |
MailerTrait |
src/Mailer/Traits/MailerTrait.php |
Shared state and send() template method |
MailerType |
src/Mailer/Enums/MailerType.php |
String constants for adapter keys |
MailerFactory |
src/Mailer/Factories/MailerFactory.php |
ADAPTERS map + singleton factory |
*Adapter |
src/Mailer/Adapters/ |
Concrete adapter classes |
Each HTTP-based adapter follows this structure:
class XxxAdapter implements MailerInterface
{
use MailerTrait;
public string $name = 'Xxx';
private $apiKey;
private string $apiUrl = 'https://...';
private array $data = [];
public function __construct(array $params)
{
$this->httpClient = new HttpClient();
$this->apiKey = $params['api_key'];
}
private function prepare(): void { /* map trait fields to API payload */ }
private function sendEmail(): bool { /* HTTP POST via $this->httpClient */ }
}
Resend API Details
- REST Endpoint:
POST https://api.resend.com/emails
- Auth:
Authorization: Bearer <API_KEY>
- Content-Type:
application/json
- PHP SDK:
resend/resend-php (Packagist) -- however, the adapter should use the framework's HttpClient directly (consistent with Mailgun, SendGrid, etc.), not the Resend SDK.
Payload shape:
{
"from": "Name <email@example.com>",
"to": ["recipient@example.com"],
"subject": "Hello",
"html": "<p>Body</p>"
}
Tasks
1. Add RESEND constant to MailerType
File: src/Mailer/Enums/MailerType.php
public const RESEND = 'resend';
2. Create ResendAdapter
File: src/Mailer/Adapters/ResendAdapter.php
The adapter must:
implements MailerInterface and use MailerTrait
- Set
public string $name = 'Resend'
- Accept
array $params in the constructor and extract api_key
- Initialize
$this->httpClient = new HttpClient()
- Use the Resend API endpoint
https://api.resend.com/emails
- Implement
private prepare(): void -- map $this->from, $this->addresses, $this->subject, and $this->message (with template support via $this->createFromTemplate()) into the Resend payload format:
from as "Name <email>" string
to as array of email strings
subject as string
html as string (trimmed, newlines stripped)
- Implement
private sendEmail(): bool -- POST JSON to the API with Authorization: Bearer header, return true on success, false on exception (same error handling as other HTTP adapters)
3. Register the adapter in MailerFactory
File: src/Mailer/Factories/MailerFactory.php
- Add import:
use Quantum\Mailer\Adapters\ResendAdapter;
- Add to
ADAPTERS constant:
MailerType::RESEND => ResendAdapter::class,
4. Add config section for Resend
File: tests/_root/shared/config/mailer.php
'resend' => [
'api_key' => 'resend_api_key',
],
5. Add unit tests
tests/Unit/Mailer/Adapters/ResendAdapterTest.php
Following the pattern of SendgridAdapterTest:
- Extend
MailerTestCase
setUp(): create new ResendAdapter(['api_key' => 'xxx111222333'])
testResendAdapterInstance(): assert instanceof ResendAdapter and instanceof MailerInterface
testResendAdapterSend(): set from/address/subject/body and assert send() returns true
tests/Unit/Mailer/Factories/MailerFactoryTest.php
Add a new test method:
public function testMailerFactoryGetResendAdapter(): void
{
$mailer = MailerFactory::get(MailerType::RESEND);
$this->assertInstanceOf(ResendAdapter::class, $mailer->getAdapter());
}
6. Update documentation / config stubs (if applicable)
If the project ships sample config files or documentation listing available mailer adapters, add resend to those lists.
Acceptance Criteria
Summary
Resend is a modern email API service gaining significant traction among developers (4.6M+ installs of the PHP SDK). It offers a clean REST API, first-party PHP SDK (
resend/resend-php), and a developer-friendly experience similar to SendGrid and Mailgun.The Quantum Mailer package currently supports five adapters: SMTP, Mailgun, Mandrill, SendGrid, and Sendinblue. This task adds a sixth adapter --
ResendAdapter-- following the established HTTP-based adapter pattern used by the existing adapters.Current Architecture
The mailer adapter pattern consists of:
MailerInterfacesrc/Mailer/Contracts/MailerInterface.phpMailerTraitsrc/Mailer/Traits/MailerTrait.phpsend()template methodMailerTypesrc/Mailer/Enums/MailerType.phpMailerFactorysrc/Mailer/Factories/MailerFactory.phpADAPTERSmap + singleton factory*Adaptersrc/Mailer/Adapters/Each HTTP-based adapter follows this structure:
Resend API Details
POST https://api.resend.com/emailsAuthorization: Bearer <API_KEY>application/jsonresend/resend-php(Packagist) -- however, the adapter should use the framework'sHttpClientdirectly (consistent with Mailgun, SendGrid, etc.), not the Resend SDK.Payload shape:
{ "from": "Name <email@example.com>", "to": ["recipient@example.com"], "subject": "Hello", "html": "<p>Body</p>" }Tasks
1. Add
RESENDconstant toMailerTypeFile:
src/Mailer/Enums/MailerType.php2. Create
ResendAdapterFile:
src/Mailer/Adapters/ResendAdapter.phpThe adapter must:
implements MailerInterfaceanduse MailerTraitpublic string $name = 'Resend'array $paramsin the constructor and extractapi_key$this->httpClient = new HttpClient()https://api.resend.com/emailsprivate prepare(): void-- map$this->from,$this->addresses,$this->subject, and$this->message(with template support via$this->createFromTemplate()) into the Resend payload format:fromas"Name <email>"stringtoas array of email stringssubjectas stringhtmlas string (trimmed, newlines stripped)private sendEmail(): bool-- POST JSON to the API withAuthorization: Bearerheader, returntrueon success,falseon exception (same error handling as other HTTP adapters)3. Register the adapter in
MailerFactoryFile:
src/Mailer/Factories/MailerFactory.phpuse Quantum\Mailer\Adapters\ResendAdapter;ADAPTERSconstant:MailerType::RESEND => ResendAdapter::class,4. Add config section for Resend
File:
tests/_root/shared/config/mailer.php5. Add unit tests
tests/Unit/Mailer/Adapters/ResendAdapterTest.phpFollowing the pattern of
SendgridAdapterTest:MailerTestCasesetUp(): createnew ResendAdapter(['api_key' => 'xxx111222333'])testResendAdapterInstance(): assertinstanceof ResendAdapterandinstanceof MailerInterfacetestResendAdapterSend(): set from/address/subject/body and assertsend()returnstruetests/Unit/Mailer/Factories/MailerFactoryTest.phpAdd a new test method:
6. Update documentation / config stubs (if applicable)
If the project ships sample config files or documentation listing available mailer adapters, add
resendto those lists.Acceptance Criteria
MailerType::RESENDconstant exists with value'resend'ResendAdapterclass exists atsrc/Mailer/Adapters/ResendAdapter.phpResendAdapterimplementsMailerInterfaceand usesMailerTraitResendAdapteruses the framework'sHttpClient(not the Resend PHP SDK)ResendAdaptersends tohttps://api.resend.com/emailswith Bearer auth and JSON payloadMailerFactory::ADAPTERSincludes the Resend mappingresendsection withapi_keyResendAdapterTestcovers instantiation and sendMailerFactoryTestcovers factory resolution for the Resend adapter