Designing a Event Bus for your Microservices

Synchronous http requests has it’s merits but alternatives are worth exploring in microservices world.

Designing systems in a async event-driven fashion with well defined bounded context will guide your services to be independent, isolated and decoupled from each other.

Designing microservice on just synchronous http calls creates coupling between them that will affect productivity of the teams.

Async Messaging

Event driven microservices requires you to choose a messaging platform. There are a good number of messaging queues out there but nowadays my favorites are by far Kafka and NSQ.

Once you choose your messaging platform you will need to get a client for producing and consuming messages in your microservices, something like this.

Invoices API — A microservice exposing invoice resources

Invoices API POST /api/invoices

Reports Service — A microservice which listen to domain events from other services. Store data in a denormalized fashion and expose a API for retrieving the aggregated data.

Reports Service handling invoice created event

Notifications Service — A microservice responsible for sending notifications like SMS, Push, SOAP

Notifications Service handling invoice created event

As you can see dealing with the client approach has some drawbacks like:

  • Boilerplate code for publishing and consuming events spread around services
  • If in a near future you decide to change your messaging system you must to refactor all NSQ references over services

To fix this let's define a package with an well defined interface for emitting and listening for events.

Extract a Event Bus Wrapper

Let's create a tiny wrapper around the messaging platform where package users can easily emit and listen to events.

nsq-event-bus

Now let's refactor our code for using this new abstraction. The event bus package was designed to reduce boilerplate and remove the pain when emitting and listening for events in your microservices architecture.

With the event bus package created, let's refactor our services for using this tiny abstraction.

Invoices API — After an invoice is created emits an event and let other services know about that "fact".

Reports and Notification Service — both listen to invoice events

Conclusion

Message-Driven architecture is the main element when designing microservices and reactive systems. With this tiny abstraction developers know how to emits and listen to domain events without effort.

If you decide to use an messaging platform like Kafka for storing these "facts" all you need to do is publish a new version of your event bus package.

Show me the code

Feel free to take a look at the event bus package https://github.com/rafaeljesus/nsq-event-bus

https://github.com/rafaeljesus/rabbus