3

I recently faced a problem when I designed the microservices architecture of our new system. To give more context on that, let's suppose that we have two different services.

  • A service is responsible to make payments and the other one

  • B service is responsible to keep track of the orders.

We have a use case that we need to update an order state from the service A.

We have these states in an enumeration list inside the service B.

How can I avoid the sharing of this enumeration between two services? I need to have decoupled services.

Please feel free to ask for clarifications.

  • have service A call service B? – Ewan May 11 '18 at 10:11
  • What do you mean by that? – pik4 May 11 '18 at 10:13
  • A.TakePayment() { //do payment; bClient.DispatchOrder();} – Ewan May 11 '18 at 10:14
  • So, yes. But they shouldn't share the states. – pik4 May 11 '18 at 10:20
  • what do you mean by "share states"? if A pulls a nuget package for bClient and uses it, is that "sharing?" – Ewan May 11 '18 at 10:22
3

There is no way. If both your services have business logic concerning the order state, both services will have to know about the different possible states.

You cannot have a meaningful conversation with someone about, e.g. playing soccer, if not both of you know something about the game. Same scenario.

  • But what about if you have multiple enumerations? Then you need to change these enumerations everywhere. – pik4 May 11 '18 at 10:19
  • @pik4 Yes, you can store the enumeration in both microservices. But then you need to think about how to change it. If they won't change very often (say once a year), you could easily just have the same enumeration class in both codebases. Thats duplicating code; you would need to choose which benefits and which pains to have. – marstato May 11 '18 at 10:21
  • In a big system, you can have a library to store all of these enumerations. But in this case, you violate the coupling part. – pik4 May 11 '18 at 10:28
1

To completely decouple your services you need a messaging layer such as RabbitMQ

Payment Service

public void TakePayment(Payment p)
{
    //payment taking logic
    messageQueueClient.Publish(new PaymentTakenMessage() { orderId = p.orderId });
}

Then we can trigger B from those messages

Order Service

public void main()
{
    messageQueueClient.ListenFor<PaymentTakenMessage>(paymentTaken);
}

public void paymentTaken(PaymentTakenMessage m)
{
    var order = orderRepo.GetOrder(m.OrderId);
    order.State = OrderState.Processing;
    orderRepo.Save(order);
}
  • Good point but let's suppose that you cannot have queues and need an HTTP Rq. – pik4 May 11 '18 at 11:24
  • my answer is going to get very long if I cover every scenario. Obvs you could replace orderRepo or even messageQueueClient.Publish with orderService if you wanted. I dont understand your question – Ewan May 11 '18 at 11:27
  • Ok. Let's suppose that you want to make the state of an order from Initiated to Processing, in Order Service. But you need to update this state when the payment is completed in Payment Service. How can you update the state without knowing the possible values? Coz in microservices you shouldn't share these values between services, right? – pik4 May 11 '18 at 11:36
  • edited. only the order service knows about the state values, and the payment service just says "payment has been taken!" – Ewan May 11 '18 at 11:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.