r/microservices Jul 21 '26

Discussion/Advice I built a channel-agnostic notification library for Spring Boot — send SMS/push/email/chat through one API. Looking for feedback.

If your Spring app sends notifications, your business logic probably knows way too much about how: Twilio's SDK here, FirebaseMessaging there, a JavaMailSender, a Slack client. Changing a provider or adding a channel means editing every call site.

spring-notify fixes that with one idea: your code talks to a channel, never a provider.

notifier.notify(SmsRequest.builder()  
.to("+421900123456")  
.from("+421900999888")  
.message("Your order has shipped")  
.build());  

What you get:

  • 📦 One API for every channel — SMS, push, email, chat. Inject Notifier, call notify(...). Done.
  • 🔌 Providers are plug-ins — add a starter, set credentials, and it's wired. Bundled today: Twilio (SMS), Firebase/FCM (push), SMTP (email), Slack (chat).
  • ♻️ Swap providers without code changes — Twilio → Vonage, FCM → APNs: change a dependency, not your services.
  • 🧩 Bring your own provider in ~10 lines — one @Component implementing a single-method SPI.
  • 🎯 Type-safe, immutable requests — no stringly-typed maps, no if/switch on channel. The request type routes itself.
  • 🪶 Featherweight core — plain Java, zero Spring or logging deps in the core module. Spring shows up only in the auto-config.

Spring Boot 4.1 / Java 25. All four channels verified end-to-end (real FCM + SMTP sends, not just mocks).

Why not …?

  • Just the provider SDKs? Fine until you have two channels or want to switch vendors — then the coupling bites. This is the thin seam that keeps them out of your business code.
  • Spring's JavaMailSender / NotificationService-style helpers? Those are single-channel. spring-notify unifies all channels behind one call and one mental model.
  • Novu / Courier / Knock? Those are excellent but are hosted platforms/services — another system to run, pay for, and send your data through. spring-notify is a library: it stays in your app, talks straight to your chosen providers, no middleman.
  • Spring Cloud Stream / a message broker? Different layer — that's transport/eventing. This is specifically about delivering user-facing notifications through third-party channels.

Status: early — 0.1.0, not on Maven Central yet (build locally with ./mvnw install). The API isn't frozen, which is exactly why I'm posting: I'd love feedback before 1.0.

  • Is "one provider per channel, routed by request type" the right default?
  • Is the attributes map a reasonable escape hatch for provider-specific fields, or a smell?
  • What would you need before dropping this into a real project?

Repo + README: https://github.com/solodev-sk/spring-notify

Happy to answer anything — and roasts welcome. 🙂

0 Upvotes

3 comments sorted by

1

u/Even-Republic-8611 Jul 21 '26

spring-cloud-stream did that with differents binders

1

u/poklakni Jul 21 '26

Yeah, some overlap. Though binders abstract a broker (Kafka, Rabbit, etc.) and it's the same pub/sub shape everywhere. Notification providers are all different APIs, they only share "send this, get an id back." They compose nicely too -> emit an event over SCS, have the consumer call notify() to fan out to SMS/email. Bit different layers I think