10

I have a number of web services that form a web application. Clients can access these services through REST APIs calls.

Should these services be able to talk directly to each other? If so wouldn't that make them couple which goes against the concept on microservices?

Should the client call them directly one after another to get the data it needs to load up a web page on the client?

Or should I have another layer on top of my services, that handles a request from the client, fetches the data for that request and then sends it back to the client?

  • If things are completely uncoupled then they're completely separate products. So the user would have to log into Contoso Login, then Contoso Login would say "You are now logged in!"... and then they go to Contoso Sensitive Data Storage, tick the box that says "Yes, I'm logged in"... then copy-paste the data from that into Contoso Data Processor... – immibis Jan 11 '17 at 4:41
14

If you want your services to look like on this picture, then yes: enter image description here It is not like you can't do it, but most of the time it will have bad consequences. Communication through REST will not decouple your services significantly. When some service interface changes, all dependent services most likely have to be changed and redeployed. Also while redeploying service, you will have to put all dependent services down, which is not considered a good design for high availability standards.

In the end, you will have microservices application which is slower than alternative monolith app would be, but having almost all the same problems!

I have to disagree with @Robert Harvey

In practice, however, one or more of your microservices (perhaps all of them) will talk to some central data store like a SQL database.

Integration database is well-known antipattern

A much better solution is to use publish-subscribe pattern in order to make communication between your services asynchronous:

enter image description here

Please take a look at CQRS/ES way of implementing this method of communication, Greg Young and other guys offer tons of nice videos on the topic. Just google for "CQRS/ES" keyword. In this approach, each service will become publisher and subscriber at the same time, allowing services to be much less coupled.

Here is a good series of articles about microservices that sheds the light on the controversy around the topic. Very detailed explanation with nice illustrations.

  • 2
    Well, first of all, I haven't heard the term "integration database" anywhere except from Fowler. Don't take something as gospel just because one guy said it. Second, you don't have enough information to call what I described an "integration database." Third, Fowler actually calls such databases useful under the right circumstances, in the very same article you linked. I like the idea of an event bus, though I don't see how it's all that different than calling the microservice's usual API unless you can increase efficiency. – Robert Harvey Jan 10 '17 at 15:59
  • Thank you Robert, I've linked Fowler's article to better illustrate idea, not to argue from authority. The way you described that approach sounds very much like integration database one. If it is different - that is not obvious at all. Regarding right circumstances - I think that integrating microservices through database is not a good idea as it pushes us back to a monolithic architecture. – IlliakaillI Jan 10 '17 at 16:11
  • OK, but your microservices will all talk to some database eventually. Can you explain in a little better detail how coupling is decreased on an event bus? – Robert Harvey Jan 10 '17 at 16:12
  • 1
    You can't categorically state that as an absolute. There might be two services that need the same information in the same database, they only need it occasionally, there's no scaling problem to access it that way, the two services are already accessing the database for other purposes anyway, so standing up a service bus or API endpoint just to accomplish that would be ridiculous. – Robert Harvey Jan 10 '17 at 17:14
  • 1
    But to achieve business value, you want to combine data -- "show me all of the sewer systems that will have insufficient storage capacity given the following radar data of incoming rain, and color this map of municipalities using the result". If you split all your data into services, it just means that you can combine the data only later. If you forbid the services to talk to each other, you just force yourself to move all the data to some client and join the data there. You WANT to couple data somewhere, as that is what in the end gives an application value. – RemcoGerlich Jan 10 '17 at 22:17
8

You'll get a lot of very good ideas from reading what Udi Dahan has to say about SOA.

A service is the technical authority for a specific business capability. Any piece of data or rule must be owned by only one service.

What this means is that even when services are publishing and subscribing to each other’s events, we always know what the authoritative source of truth is for every piece of data and rule.

Also, when looking at services from the lens of business capabilities, what we see is that many user interfaces present information belonging to different capabilities – a product’s price alongside whether or not it’s in stock. In order for us to comply with the above definition of services, this leads us to an understanding that such user interfaces are actually a mashup – with each service having the fragment of the UI dealing with its particular data.

Specifically with regards to UI composition, Mauro Servienti's article on UI Composition is a good starting point. See also Udi's video, available here.

Should these services be able to talk directly to each other? If so wouldn't that make them couple which goes against the concept on microservices?

If two services exchange messages with each other, then you are going to get some coupling. The primary answer there is that they couple to the API of the other service -- the contract that the service promises to keep stable even when its internals are changing.

Beyond that, techniques like service discovery can ease the dependency on a specific service provider, and message brokers can decouple the producers and consumers (they still need to understand each others messages, and how to interact with the message broker's API -- there's no magic).

6

It depends on what you mean by "directly".

It is perfectly fine, according to the microservices architecture, to have microservices that invoke other microservices, either on your own server, or even on external servers, via some interface like REST.

What is not fine, is for one microservice to invoke another using direct method invocations; that would make both microservices part of the same monolith.

  • it is not fine and will have bad consequences. See my answer for more details. – IlliakaillI Jan 10 '17 at 15:40
  • @IlliakaillI I am saying that it is fine "according to the microservices architecture". I am not suggesting that the microservices architecture is free from consequences, or that there are no improvements that can be made to it. The question here is "is X by the book, or not?" and the right answer is that given the correct definition of X, it is by the book. – Mike Nakis Jan 10 '17 at 17:57
  • Is there a "reference book" that tells you how to build real "microservices architecture"? Microservices becoming a buzzword nowadays and many people wrote books about how to build monoliths on top of REST. Just look at that first diagram in my answer, it does not make sense to build system in that fashion. If you do for some weird reason - you definitely doing it wrong. You better go with monolith instead. If you back your design choices by blindly referring to some books (making an argument from authority) it is not a right way of approaching software design. – IlliakaillI Jan 10 '17 at 19:53
4

Should these services be able to talk directly to each other? If so wouldn't that make them couple which goes against the concept on microservices?

Coupling is not a bad word. Every application already has a certain degree of coupling; the applications that talk to your microservices are already coupled to the microservices, otherwise they wouldn't work.

What you're really after with microservices is loose coupling; you can achieve that by simply having one microservice interrogate the other through its public API or using an event bus.

In practice, however one or more of your microservices (perhaps all of them) will talk to some central data store like a SQL database. Depending on how you want to accomplish your goal, you might simply have one microservice alter the database data in some way, which the other microservice will query to pick up the change.

  • 2
    "Integration database" is well-known antipattern, see my answer for more details. – IlliakaillI Jan 10 '17 at 15:41
2

It seems that when speaking about SOA's and architecture in general, people get caught up in semantics and jargon. What makes a service "micro"? Ultimately, it is some set of characteristics that, in whatever "scoring system" you're using, clearly don't make the service "non-micro." What was it that the supreme court justice said about indecency? "I'll know it when I see it."

I'm sure some people will say this is a non-answer, but then they're missing the point. Micro-service architectures are intended to avoid several problems, among them the issue of "tight coupling." So, if you end up creating a tangle of micro-services that depend on too many fine details of each other, you've created a tight coupling that -- whether you are using a pub/sub message bus or direct calls -- destroys your ability to compose new solutions from the pieces, reconfigure individual pieces without bringing down the whole system, etc etc

1

Should the client call them directly one after another to get the data it needs to load up a web page on the client?

It depends; however, I'd suggest providing directly usable capabilities to the client and hiding (encapsulating) the details of how results are assembled (e.g. via multiple micro services).

If too much logic is involved in combining individual micro-service results by the client, that may inadvertently cause some business logic to creep into the client. It can also expose more of your internal architecture to the client than you would like, hindering later refactoring of the microservices.

So, that means with microservices, sometimes it is helpful to have a wrapper microservice that provides the client an endpoint having useful abstractions and that performs a higher level coordination of other (perhaps now more internal) microservices.


(Further, round trips to the client are likely more expensive than from your microservices to each other.)


If you look at the direction being taken by GraphQL, for example, you'll find clients issuing directly relevant queries to an endpoint, which may or may not be implemented as a collection of micrservices. As the architecture of the microservices is hidden behind GraphQL, that makes the architecture easier to refactor and also friendlier to the client. See, for example, https://stackoverflow.com/a/38079681/471129.

1

The main purpose of micro-services is to make your application loosely-coupled. Therefore, services can not call each other. Otherwise, it will be tiedly-coupled. But what are we gonna do if we have two services that need to be share data? The answer is Message Broker. So the service that get data from client can share the data to central message broker, then the services have to use that data can consume it, transform it, and put it into its own data storage. I recommend Kafka because you can join data from different topic on the fly with Kafka Stream. PS. better to separate your micro-services by feature.

protected by gnat Jan 11 '18 at 11:35

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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