문제

In a microservice-based system, it exist some principles. Sam Newman often refers to them as these:

  1. You should always model your application around the domain
  2. A culture of automation. Automate whats possible to automate
  3. Hide your implementation details
  4. Decentralize everything
  5. Deploy indepentently
  6. Isolate your failures
  7. Highly observable

https://samnewman.io/talks/principles-of-microservices/

When building a system where you microservices reflects the domain, which basically means to me that you have one microservice for each defined bounded context, I find it quite difficult to deal with a servicebus architecture and events published.

An example:

Lets say you're creating a system for a foodstore chain where the customers can sign up for a bonus program, which gives them x % back for every purchase they make.

So you and your team sits down with the customer to identify the domain and you identified at least two bounded contexts. The contexts identified are: Customer and Loyalty. You start out by making two microservices based on these two contexts, CustomerService and LoyaltyService.

The business defines a rule that, whenever a customer signs up, a 5 % discount coupon shall be sent to the customer's email.

The CustomerService exposes an API to create the customer in the database and when the customer is created an event CustomerCreatedEvent is published on the servicebus. As the LoyaltyService is interested in this event to send the 5 % discount coupon, it has to subscribe to this message. In NServiceBus, which is my prefered servicebus, its done this way:

public class SomeClassName : IHandleMessage<CustomerCreatedEvent> 

You might already figured it out, but this is where I struggle to find a good solution to be "compatible" with the principles of microservices. How should the LoyaltyService be able to subscribe and deserialize this event without having a reference to CustomerService either over NuGet or direct reference? Should we duplicate our code so that the CustomerCreatedEvent are defined in both services?

Any suggestions, blog posts, books, pluralsight courses on how to create a domain driven microservice architecture application would be very helpful.

Thanks.

도움이 되었습니까?

해결책

If both projects use .NET, nothing prevents you from having a common library which would define the base classes.

In a case where you cannot or don't want to have a common project, such as when two services use a different technical stack (say one is in Haskell, another one uses PHP), you can:

  • Either duplicate the class,
  • Or create the class automatically based on Swagger or whatever else you use to advertise the interface of a service,
  • Or create a separate class which only takes the properties you need, as opposed to every property available in the class of the consumed service.

In all three cases, you have the benefit of not being linked to the model of the class from the consumed service. As soon as the fields that you use stay unmodified (i.e. there are no breaking changes), you're good to go.

다른 팁

There will always be some level of dependency in any system which is unavoidable.

In the case of the LoyaltyService, imagine it existing with no dependencies to CustomerService. Conceptually then, you can have loyalty without having a customer, which doesn't make sense.

So the dependency on the CustomerCreatedEvent is perfectly acceptable. The details of the object can limit the involvement between LoyaltyService and CustomerService. The more lightweight the event object, the lower the level of coupling.

The aim for any system design is loose coupling, not zero coupling. Here is a definition of loose coupling that is useful:

Loose coupling is an approach to interconnecting the components in a system or network so that those components, also called elements, depend on each other to the least extent practicable. Coupling refers to the degree of direct knowledge that one element has of another.

https://searchnetworking.techtarget.com/definition/loose-coupling

Loosely coupling is the key for re-use. Create/Define an exchange format (preferably something open and established like XML Schema or use JSON) and send serialised messages to your messaging sub-system. Now you are open to read and process the message in all interested receivers (eg: your loyalty service). Use your messaging system to route the messages accordingly (eg: Publish-Subscribe or any other technique you like...)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 softwareengineering.stackexchange
scroll top