I am new to event-driven microservices and am interested in what is the best way to display data in a web application in such an architecture.
Let say I have 2 microservices: Orders and Products with separated databases per service, and nservicebus to send events.
What I can display the list of orders in the web app? Should I add one more database for the Web app and some SubscriberService that subscribes to events and stores replicas of data when orders or products were changed? Or it is better to add web api in microservices in order to receive data in the Web app? I also know there is an option to use ETL to populate replicas to WebAppDatabase
Related
I am new to microservices and trying to break up a big monolithic application into microservices. While scoping the microservice I am unable to decide whether I should go for a data duplication between services or ignore SRP by clubbing all requiring the same data into 1 service. Following is the scenario.
I have a service which receives Customer order say build a car with these parts and features. Now I have other 2 functionalities which uses the Parts and features to derive some runtime value say ;
If the order contains part A and Feature A then perform X operation. As each of these functionalities have there respective UI for configuration and runtime engine to derive the output and most of the time changes only comes in these respective function blocks, I thought of creating the separate microservices.
Creating the separate microservice would need data(Parts and Features) to be duplicated. Another option could be given each of these service uses the same data is clubbing all of them into 1, but with that I again create a big service which if goes down will stop all 3 functionalities and is against SRP. Another option could be when the data is required by the other 2 services make a call and get it from Order Service, but that is making it highly dependent and getting the data over network for each operation.
Can anyone suggest what would be ideal to do in such case.
Microservice should communicate via events using publisher/subscriber model and topics. See the tri-lateral design pattern. In a pub/sub system the producer writes the event to the topic and a broker makes it available to each subscriber, aka microservice. This is one advantage of eventing, one producer, and many consumers.
Order A has a BOM that expresses parts and features an order represents. When the order is placed, other services need that information such as the feature/part microservice and UI components and their respective datastores. For example, define two topics parts-ordered and features-ordered.
The order microservice writes to the parts and features topics respectively. The feature, parts, and UX microservices read and act upon those events.
You need to make a choice about your system of record. You can write to an orders DB before publishing the events, or let the pub/sub it. In your example, it sounds like you are talking about three different tables; order, parts, and events. That decomposes cleaning into the microservices you describe where each maintains the data it is responsible for. I'd be inclined to just use the pub/sub as your audit trail.
If you are writing in Go we have blueprints for the most common design patterns.
First, you mentioned that you are trying to convert the monolithic application into microservices. You can create/caters the microservices on basis of domain data, we can be called it domain-driven architecture.
Suppose you have the business functionality for customer data, customer order, customer order handling, and customer payment. And currently, it's part of a monolithic application. So you can create the subdomain for each functionality like Customer domain, Order domain, order handle domain, and payment domain respectively. Each domain contains several microservices depends on the business requirement.
For e.g you can check the Amazon website, In personal/customer data, you see the customer name, phone number, address, billing account information, delivery address type(office/home). In this case the under customer domain, there will be 3 microservices required(It totally depends on your domain design). One for customer(handles customer name, phone number, reference of Billing account id, reference of address id), second for Billing account(Billing account number, billing account information, reference if customer id), third for Address data(customer office address, preferable address). And for each microservice, there will be a dedicated database/buckets, Only that microservice can change/add the data. If any other microservice wants to add/update/get data, it needs to be get by calling that microservices HTTP endpoint over the network.
Updating the data in other microservice::
Now coming to your question about data duplication, Let's consider the above example.
If Customer microservice wants to store/ cache the billing account data for some purpose, that microservice can store that data in the database but again Customer microservice needs to make sure that, the current data of the billing account is always real one and not the old one. For this customer, microservice needs to listen to the event whenever there is update in billing account data, so old data in billing account gets purged and customer microservice always has the latest data of billing.
you can read here about event driven architecture.
https://en.wikipedia.org/wiki/Event-driven_architecture#:~:text=Event%2Ddriven%20architecture%20(EDA),sale%22%20to%20%22sold%22.
You can read more about this at the below links about Domain driven design.
https://www.thoughtworks.com/insights/blog/domain-driven-design-services-architecture
https://en.wikipedia.org/wiki/Domain-driven_design
This is my free book :)
https://github.com/vaquarkhan/microservices-recipes-a-free-gitbook
If you want to create microservice then need to follow microservice guideline.
Now come to real world :) really difficult to meet all microservice requirements as database has own licensing cost etc. so you can choose pragmatic microservices. You can get started with them faster and pick and choose the pieces that make sense for your team.
Design Domain driven design oriented microservice : DDD talks about problems as domains. It describes independent problem areas as Bounded Contexts and each Bounded Context correlates to a microservice.
Where to draw the boundaries is the key task when designing and defining a microservice.
DDD patterns help you understand the complexity in the domain, the domain model for each Bounded Context, you identify and define the entities, value objects, and aggregates that model your domain. You build and refine a domain model that is contained within a boundary that defines your context. And that is explicit in the form of a microservice. The components within those boundaries end up being your microservices.
https://martinfowler.com/bliki/AnemicDomainModel.html
https://github.com/vaquarkhan/Domain-driven-design
https://github.com/vaquarkhan/ddd-by-examples.github.io/blob/master/ddd-factory.pdf
Now you can create layers on top of you microservice and build complex logic using orchestration and choreography.
Example :
Gateway Customer order Application layer microservice --domain model layer microservice infrastructure layer
There are various ways to decompose an application into services.
1.Decompose by business capability
2.Decompose by subdomain
And there are various ways for data management also
SAGA
API Composition
Database per service
Please go through with the link for more details click
If my company sole purpose is processing a specific payload, but there is lot of orchestration for it. Should the orchestration, be in a separate domain. Lets say, payment is what the company does, but there is a workflow service, for that payment payload? If that is in a seperate domain, how should the workflow service domain talk to payment service domain?
It's better to use Event Driven Design which powered by message services like RabitMQ (or Kafka, MSMQ, or ..). It's not recommended to speech microservice each other directly via APIs. On the other hand to aggregate, some information from multiple services you can use 2 techniques, first using a BFF (back end for frontend layer), Second use a materialized view to gather information from many services.
I have some experience doing REST microservices architecture, but now I want ot start using kafka as a message provider in my Event drivenr architecture.
I have an issue understanding how the communication works between microservices.
Lets say I have two microservices one that deals with users and another one with messages between users.
Users can be created, and then users can send another users messages, and I am planning to do them with topics and then store them in a MongoDB.
How do I retrieve this messages in a event driven architecture?
EDIT: The example is quite simple is just for educational purpose and to practice with Apache-Kafka.
For clarity, let's call user messages instead as posts.
One possible architecture is all users create post objects, which are sent to a Kafka topic that contains information such as timestamp, sender and sendee, rather than directly as a database insert.
Out of Kafka, you write some consumer process(es) to poll all messages from the topic, then insert to Mongo (and possibly also a search engine or machine learning / text categorization model).
On another user account, they (periodically) query the database for all posts sent to them, as Kafka is not indexable by a user account and one topic per user is not a scalable design pattern.
The gist is that users aren't directly retrieving posts from Kafka, but you've buffered messages in Kafka so they can be forked into different models so that you can decouple your application from a Mongo dependency (except for having a search feature)
From events, you can separate out "posts-new", "posts-edit", and "posts-deletes" as separate topics. For more context about designing this, you can look into Event Storming
Imagine the following:
You have two microservices called team and player each one with your own and separated databases (postgres).
I need to do association between team and player, so I need to store this relation inside player with team id attribute.
I have two options:
1) using kafka, for every team inserted on database I send an event and player listen to this event and update its own team table inside player microservice. So, player microservice will have the information about team and player entities in order to make the relationship between them.
We have some drawbacks here about data replication and integrity. Could be avoided using event sourcing and cqrs.
2) Call microservice team in order to list team on view, make the association and post to player microservice.
Drawbacks: calling http the team service could be down.
What is the correct approach to communicate between microservices in order to archive dependency and doing releationship between microservices. Have data replicated on step 1 is reasonable??
I would say that option 1 is favourable. You are then keeping the services decoupled/independent. It also scales, as other future services can then subscribe to the same events.
I don't think data replication is such an issue. I prefer DDD approach whereby individual services control their own data in their own context. Services can then made as simple as they need to be to serve their specific purpose.
We are evaluating a move to microservices. Each microservice would be its own project developed in isolation. During planning, we have determined that some of the microservices will communicate with other via REST calls, pub/sub, messaging (ie. a order service needs product information from product service).
If a microservice depends on retrieving data from another microservice, how can it be run in isolation during development? For example, what happens when your order service requests product details, but there is nothing to answer that request?
What you probably need is an stub rest service. Create a webapp that takes the expected output using a path that is not part of the public api. When you invoke the public api it sends what it just received
If a microservice depends on retrieving data from another microservice, how can it be run in isolation during development?
It should be always temporally isolated from other services during development and production as well.
For example, what happens when your order service requests product details, but there is nothing to answer that request?
This is a place where design flaw reveals itself: order service should not request product details from another service. Product details should be stored in the message (event) that order service will be subscribed to. Order service should be getting this message in an asynchronous manner using publish-subscribe pattern and saving it in its own database. Data about the product will be stored in 2 places as the result of that.
Please consider reading this series of articles about microservices for more details. But in a nutshell: your services should be temporally decoupled, so when your product service is down - order service can continue its operations without interruptions. This is the key thing to understand about good distributed systems design in general.