How do you develop a microservice in isolation when it depends on other microservices? - microservices

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.

Related

How to Transfer Data Between Multiple Microservices?

As part of my project, I'd like to use microservices. The application is a store website where the admin can add products and the user can order and buy them.
I envision implementing four services: admin service, user service, product service, and order service.
I had trouble with handling data between multi services but it's solved by duplicating some necessary data using message brokers.
I can do this solution between product and user and order service because I need some of the data not all of them
Now, my question is about handling admin service because in this service I need to access all of the data, for example, the admin should have a list of users and the ability to add new products or update them.
how can I handle data between these services and the admin service?
should I duplicate all data inside the admin service?
should I use Rest API?
no thats wrong. it seems you want run away from the fact. in general duplication is an anti-pattern mostly in case you describe.
the way you thinking about admin-service is wrong.
because in this service I need to access all of the data
i dont think you need to have such a service. accessing the data based on users must be handled by Identity server(oidc Oauth) which is the separated service and handle the accessing end points .
for example the product-service provides 1-return product list 2-return individual product data 3-create data. the first two can access by both user and admin but the 3rd must be accessed by admin. one of identity server duty is to identify user in case of user interaction(login) with services.
ADMIN Scenario
user-client request create product endpoint(services eg:product.service).
client-app(front end app) is configed with identity server and realize there is no require identity tokens and redirect to identity server login.
NOTE: there is also identifying the client-app itself i skipped.
user-client login and get require token that based on his claims and roles and etc.
user-client request create product endpoint with tokens included in request header
endpoint (product service) receives the request and check the header (the services also configured base on identity server and user claims)
get the user claims info.
the create-product requires admin role if its there then there we go otherwise no access.
the image uses identity server 4 . there are also several kinds and also you can implement by your self using 0AUTH and oidc protocol libraries.
so the admin just request to the certain service not getting data through the separate service for this goal.
Communication between Service:
the most struggling part of microservices is the wiring it up. the wiring is directly the consequence of your design.(recommand deep study on Domain Driven Design).
asynchronous communication :
to avoid coupling between services mostly use asynchronous communication which you pass event eg:brokers like rabbitmq and kafka..etc , redis etc. in this communication the source service who send event does not care about response and not wait for it.just it always ready to listen for any result event. for example
the inventory service creates item
123|shoe-x22|22units
and this service fire event with data 123|shoe-x22(duplicate maybe or maybe not just id) to product service to create but it does not wait for response from product service that is it created successfully or not.
as you see this scenario is unreliable in case of fault and you need handle that so in this case you have to study CAP theory,SAGA,Circuit-breaker.
synchronous communication :
in this case the service insist to have response back immediately. this push service to become more coupling. if you need performance then you can use gRPC communication other wise simple api call to the certain service. in case of gRPC i recommand using libraries like MassTransit
which also can be used for implementingf gRPC with minimum coupling.
Some of Requests need data from multiple services
if you are in such situation you have two options.
mostly microservices architecture using APIGATE WAY (EG:nginx,OCELOT,etc)
which provide reverse-proxy,load balancing,ssl terminations etc. one of its ability is to merge the multiple responses from a request.but it just merge them not changing the data structure of response.
in case of returns desire response data structure you may create an Aggregator service which itself calls other two, gathers data and wrap it in desire format and return it.
so in the end still the Domain Driven Design is the key and i think i talked tooooo much. hope help you out there.

Microservice Data Duplication vs Single Responsibility

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

In a domain-driven microservice, should you communicate outside the domain?

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.

What are the "real-world" solutions for not duplicating data in microservices?

Suppose that I have a microservice for messaging. The microservice knows how to send emails. The service have templates of emails that have some sort of "template engine" like pugjs, and can replace data in the body of the message.
I have an user service (used for authentication/authorization for example), and a bank account service (each user have one). Between the User microservice and Bank Account microservice it's clear that we don't have to duplicate any data than de user's uuid.
But I want now to send every day a message to each user with their account statement. The Messaging microservice needs data from the User microservice and the Bank Account microservice.
Okay... This is a small case of the real world. Now I know that to have the benefits of decoupled microservices I must follow some rules:
I can't share databases between microservices
I can't make synchronous requests between microservices
Okay... I can use a broker and each time a new user is created/updated the Messaging microservice can store that data. But really, this is a stupid thing:
I don't want to have inconsistency with this data, and keeping things sync is hard
The development time and complexity of the Messaging Microservice must now consider: listen and extract the relevant data from events, keep data consistent about other domains/services, managing the saved data on database
And think about a Messaging microservice. Really I must store all the data needed to parse the templates?
I read a lot about microservices and people creating rules for their simple examples. But I never really saw a good explanation and real-world examples like above.
So how to have the microservices above without data duplication?
In your domain example I would not let the message service know anything about bank or user details. Instead the message service should just receive instructions to send messages to recipients along with the given content. I would use a dedicated scheduled job (maybe implemented as an account notification service) that performs the work of acquiring the user and account data from the corresponding services, compiles the information for the message service and instructs it to actually send the messages. This introduces another "higher level, business purpose entity/service" but allows you to keep a clear separation of concerns.
In general it will happen frequently that your "basic" domain services are used by another service that represents a specific business purpose and requires their data. Dependency in itself is not a bad thing as long as concerns are seperated clearly and interfaces versioned, changes communicated etc.
Don't forget the whole idea of microservices is for allowing teams to have dedicated responsibilities with clear interfacing. It is about organization as much as it is about architecture.

how Orchestrate microservices

I've been triying to migrate part of our soa architecture (Mule ESB) to microservices (Spring Boot stack), but I'm facing a problem related to large flows where we have several orchestations.
Basically We a have a flow which has an user id as input and the response is compounded of user account, creditcards data, stocks and loans.
In this flow we have, at the beginning, a splitter (allows to send concurrent requests) and we send requests to account backend, 3 different credicard partners, stock partner and loans partner, at the end there is an agregattor (wait to all responses and merge all of them) and finally a node for prepare the response (apply business logic).
During the migration we have developed an account microservice, loan microservice, stock microservie and creditcard microservices (1 for each partner). The problem here is the orchestation, We can't use and event model approach because we need to get all responses in a certain point. We considered the choreography approach too, but we don't want to add logic related ot how orchestrate calls to our microservices because that would be a stepback to heavy coupled services (N*N connections).
We are thinking on make a new microservice that will be used as an orchestrator, but we don't know if this will be a good solution for microservices concepts.
Note: The front end can't make the orchestrations because it is a closed product and we can't touch it.
Thanks in advance.
We are thinking on make a new microservice that will be used as an orchestrator, but we don't know if this will be a good solution for microservices concepts.
From all you described that sounds like the most reasonable thing to do. You describe this service as having its own business purpose which indicates to me the potential need for a dedicated service. And the fact that it requires input from other (more basic) services would not be unusual for a complex domain service. Also you already listed the alternative of aggregating on the front end as something that doesn't work in your domain.
Something to consider is just making sure that the development teams for the basic services treat their APIs as customer facing (with the customer being your other services). That means they have to do clean work in terms of versioning/deprecating/etc.
And the downstream services need to treat the consumed APIs like they would a 3rd party API. For example Google went so far to allow internal service consumption be charged real money to incentivize optimizing the implementation of dependent services.

Resources