Resend email transport adapter for the Firefly Framework notifications abstraction — drop it on the classpath, set one property, and send email through the Resend API reactively.
- Overview
- Features
- Requirements
- Installation
- Quick Start
- Configuration
- How It Works
- Documentation
- Contributing
- License
fireflyframework-notifications-resend is a pluggable email provider adapter for the Firefly Framework notifications subsystem. It implements the EmailProvider SPI defined in fireflyframework-notifications-core and routes outbound email through Resend, a developer-focused transactional email API.
The notifications core defines a transport-agnostic contract (EmailProvider, EmailRequestDTO, EmailResponseDTO) so that application and domain code never depends on a specific email vendor. This module is one of several interchangeable backends for that contract: you select it at runtime by setting firefly.notifications.email.provider=resend. Swapping vendors becomes a configuration change rather than a code change.
The adapter is fully reactive (Project Reactor Mono) and builds on fireflyframework-client's RestClient/ServiceClient, so it inherits the framework's HTTP client conventions (JSON content negotiation, bearer-token auth headers, and a named client instance). Auto-configuration wires everything automatically once the module is on the classpath and a Resend API key is present — there are no beans to declare by hand.
Where it sits in the framework:
- Core SPI —
fireflyframework-notifications-coredefines theEmailProviderinterface and email DTOs this adapter implements. - Sibling adapters — other email/SMS/push providers implement the same SPIs; only one email provider is active per application, chosen by
firefly.notifications.email.provider. - HTTP client —
fireflyframework-clientsupplies the reactiveRestClientused to call the Resend REST API.
EmailProviderimplementation (ResendEmailProvider) backed by the ResendPOST /emailsendpoint.- Reactive, non-blocking delivery returning
Mono<EmailResponseDTO>; the blocking-friendly call is dispatched onSchedulers.boundedElastic(). - Spring Boot auto-configuration (
ResendAutoConfiguration) activated by thefirefly.notifications.email.provider=resendselector and the presence of an API key — no manual bean definitions required. - Rich message support — HTML and/or plain-text bodies, multiple
to/cc/bccrecipients, and file attachments (automatically Base64-encoded with optional content type). - Sensible
fromresolution — uses the per-messagefromwhen supplied, otherwise falls back to the configureddefault-from. - Resilient by default — delivery errors are caught and surfaced as a structured
EmailResponseDTO.error(...)rather than propagating raw exceptions. - Named, secured HTTP client — a dedicated
resendRestClientis built with JSON content type and aBearerauthorization header derived from your API key. - Override-friendly — every auto-configured bean is
@ConditionalOnMissingBean, so you can supply your ownRestClientorEmailProviderto customize behavior.
- Java 21+ (Java 25 recommended)
- Spring Boot 3.x
- Maven 3.9+
fireflyframework-notifications-coreon the classpath (transitively provided by this module)- A Resend account with an API key and at least one verified sending domain/address
Add the adapter alongside the notifications core. The version is managed by the Firefly parent/BOM, so you normally omit <version>:
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-notifications-resend</artifactId>
<!-- version managed by the Firefly Framework parent/BOM -->
</dependency>This adapter declares a compile-scoped dependency on fireflyframework-notifications-core and fireflyframework-client, so they are pulled in transitively.
If your project does not inherit the Firefly parent, import the BOM in dependencyManagement (or pin an explicit <version> such as 26.05.07):
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-bom</artifactId>
<version>26.05.07</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>1. Add the dependency (see Installation).
2. Select Resend and provide credentials in application.yml:
firefly:
notifications:
email:
provider: resend # selects this adapter as the active EmailProvider
resend:
api-key: ${RESEND_API_KEY}
default-from: "Acme <no-reply@acme.com>"3. Inject EmailProvider and send a message — your code depends only on the core SPI, never on Resend:
import org.fireflyframework.notifications.interfaces.dtos.email.v1.EmailRequestDTO;
import org.fireflyframework.notifications.interfaces.dtos.email.v1.EmailResponseDTO;
import org.fireflyframework.notifications.interfaces.providers.email.v1.EmailProvider;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Service
public class WelcomeEmailService {
private final EmailProvider emailProvider; // ResendEmailProvider, auto-wired
public WelcomeEmailService(EmailProvider emailProvider) {
this.emailProvider = emailProvider;
}
public Mono<EmailResponseDTO> sendWelcome(String recipient) {
EmailRequestDTO request = EmailRequestDTO.builder()
.from("Acme <no-reply@acme.com>") // optional; falls back to firefly.notifications.resend.default-from
.to(recipient)
.subject("Welcome to Acme")
.html("<h1>Welcome!</h1><p>Glad to have you on board.</p>")
.text("Welcome! Glad to have you on board.")
.build();
return emailProvider.sendEmail(request); // -> EmailResponseDTO.success(messageId) or .error(reason)
}
}On success the returned EmailResponseDTO carries the Resend message id; on failure it carries the error reason (the exception is logged and swallowed, not propagated).
All properties live under the firefly.notifications.resend prefix, except the provider selector which is shared by the notifications core.
firefly:
notifications:
email:
provider: resend # required: activates this adapter
resend:
api-key: ${RESEND_API_KEY} # required: your Resend API key (re_...)
default-from: "Acme <no-reply@acme.com>" # optional: fallback sender when a message omits `from`
base-url: https://api.resend.com # optional: Resend API base URL (override for tests/proxies)| Property | Default | Description |
|---|---|---|
firefly.notifications.email.provider |
(none) | Selector that activates this adapter. Must equal resend for the auto-configuration to apply. |
firefly.notifications.resend.api-key |
(none) | Resend API key used as the Bearer token. Required — the RestClient/EmailProvider beans are only created when this is present. |
firefly.notifications.resend.default-from |
(none) | Sender used when an EmailRequestDTO does not specify from. |
firefly.notifications.resend.base-url |
https://api.resend.com |
Base URL of the Resend REST API. Override to point at a mock server in tests. |
The auto-configuration is gated by two conditions: firefly.notifications.email.provider=resend (class-level) and the presence of firefly.notifications.resend.api-key (on the RestClient bean). If either is missing, the adapter stays inactive and another provider may take over.
ResendAutoConfigurationis imported viaMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsand activates whenfirefly.notifications.email.provider=resend.- It builds a named
resendRestClientfromServiceClient.rest("resend")with the configuredbase-url, JSON content type, and anAuthorization: Bearer <api-key>header. - It registers
ResendEmailProvideras theEmailProviderbean (unless one is already defined). ResendEmailProvider.sendEmail(...)translates theEmailRequestDTOinto the Resend JSON payload (from,to,subject,html/text,cc,bcc, Base64attachments) andPOSTs it to/emails, mapping the response id intoEmailResponseDTO.success(id).
- Framework hub and module catalog: Firefly Framework on GitHub
- Notifications core SPI: fireflyframework-notifications-core
- Reactive HTTP client: fireflyframework-client
- Resend API reference: resend.com/docs
Contributions are welcome. Please read the CONTRIBUTING.md guide for details on our code of conduct, development process, and how to submit pull requests.
Copyright 2024-2026 Firefly Software Foundation.
Licensed under the Apache License, Version 2.0. See LICENSE for details.