This is a multi-part series on creating a microservice from scratch. It will be a production-quality application that will highlight the use of the following technologies:

  • Quarkus
  • GraalVM
  • Kotlin
  • Postgres (Persistence)
  • Panache (JPA)
  • Flyway (Database migration)
  • Kafka (Messaging)
  • Debezium, Kafka Connect (Transactional Outbox pattern)
  • Okta (OIDC)
  • Open API
  • Docker
  • Test Containers
  • Wiremock

The application will be be constructed in stages, with each stage adding additional functionality. Each release will be deployable and fully tested, but the service won’t be ready for production until the final stage.

Why Quarkus?

I have used spring boot for years and it is a fantastic framework. In the last couple of years more frameworks have started to compete in the same space such as Micronaut and Quarkus and Helidon. Quarkus, in particular, seems very well suited to a microservices architecture, with its promise of “supersonic” start up time and “subatomic” memory usage. In addition it works well with GraalVM and Kotlin. This use case will be an opportunity to test out building an application using Quarkus. To be useful it will need to incorporate REST services, persistence, messaging, security, configuration and other useful and common features.

Why Kotlin?

These days it is smart to be a polyglot programmer and there are an increasing number of excellent and mature alternatives to Java. One of the most popular is Kotlin and Quarkus provides first class support for the language.

Why Debezium?

When data is persisted in a microservice there are consumers within that service and other microservices that are interested in the persisted data changes. Change Data Capture (CDC) is a way to monitor and capture those changes. Debezium provides the services that can capture data changes and emit them as events. Compared to the alternative polling approach CDC avoids the increased CPU load of frequent polling and can reliably maintain the order of events.

The Use Case

M

ost platforms have a requirement to communicate with their users via SMS. This may be to notify them of certain actions or events or often to send a One Time Password(OTP) when used as a part of a two-factor login or step-up security. An SMS Service is a great candidate for a microservice as it has to do just one job: send SMS messages.

The simplest approach would be for the SMS microservice to just proxy to the SMS provider of choice. The service:

  • receives a request to send an SMS Message
  • transforms it to the required format for the chosen SMS provider
  • sends the REST request
  • relays a transformed response back to the caller

Image for post

Diagram 1. Sms Service as a proxy to third party provider

This approach does not offer much flexibility. The caller of the service has to wait for the synchronous reply back from the third party provider. If there is a network failure then the caller must send the message again or keep retrying. The risk of cascading failure from resource pool exhaustion is high. It would be better to decouple the calls and give the invoker of the service a way to check on the status.

For this we will have to introduce persistence to the service and messaging to guarantee delivery. We add some latency to the process but increase the flexibility and make the system more useful. And it gives us an opportunity to play with some interesting technology while building out the service.

The final architecture will look like this:

Image for post

#quarkus #microservices #debezium #kotlin

Building a Microservice From the Ground up With Quarkus, Kotlin and Debezium
2.10 GEEK