10

Imaginative setup

  • Several services
  • Each lives in its own repository
  • Each developed separately
  • Each deployed separately
  • They want to communicate via NServiceBus

Research

Examples on NServiceBus basics show how several applications, which are part of the same solution, share message definitions using another Shared library project, that they all reference. Here, if services are not part of the same solution things become complicated.

I suppose, shared project can be extracted into a separate repository and then be referenced from other repositories as a DLL or as a custom NuGet package, for example. But it creates a lot of difficulties during development and doesn't feel to be right.

In this sample http://docs.particular.net/samples/step-by-step/, there is even a note saying:

Storing all message definitions in a single location is not a best practice, but serves to illustrate how things work for this simple example.

However I yet failed to find what is a best practice.

Question: How to share message definitions between services in a proper way?

Alexei Matrosov
  • 420
  • 4
  • 10

1 Answers1

10

Your imaginative setup is good. However, rather than having one shared messages assembly, each service can have its own messages assembly, and then publish it as a NuGet package to a private repository.

So if you have the Sales service, for example, in the Sales repository, would also contain a Sales.Messages project. It the most basic form, it would contain the definitions for all commands processed by the Sales service, and the definitions for all events published by the Sales service.

It's also smart to further divide up messages between a Sales.InternalMessages and (let's just call it for now) Sales.Contracts.

Internal messages would be just messages that are tossed around within your service. Like private methods, you wouldn't want other teams to be able to invoke those from outside your service, and so you wouldn't distribute those messages externally as a NuGet package.

Then, Sales.Contracts would contain only those messages that go outside the service. Naming them "Contracts" reminds you that's what they are - a contract between services - and so you need to manage them as such. That means that changes to them need to be carefully considered and versioned as well.

David Boike
  • 18,545
  • 7
  • 59
  • 94
  • 1
    Hi David, Thanks for explanation. I think @udidahan can correct me and give more clarification here. But I think you can go with consumer driven contract approach (https://martinfowler.com/articles/consumerDrivenContracts.html) where each service can just expect some message with schema that they define and they dynamically serialize the incoming message and execute handlers. This way we end up sharing nothing among other services ( micro-services ) but than schema only. And each subscriber can write their own message s/derializer. Nservice bus will execute handler for the matched message. – Rupesh Kumar Tiwari Apr 04 '17 at 20:30