You should not follow every rule as it is.
There are many exceptions to this rule and the practices of lot of systems has proven it not to be correct for every case or system.
I disagree with this restriction that micro-service A should never call micro-service B as a general rule as it does not apply to all cases. I have worked with multiple systems using
micro-services and we where not following that.
Communication between micro-services:
You can use multiple ways to communicate between micro-services like:
Events (using queue)
Commands - direct call over API to another micro-service (which is some kind of instruction to the micro-service) which
requires a change to happen(Create, Update, Delete).
Queries - direct call over API to another micro-service (like your example of getting GUID).
Again some people will say that this is a Command as well.
Using Query as term is often combined while you use CQRS as well.
Shared Db's (most of the online resources will tell you not to do this
for multiple reasons)
In general this is not recommended approach.
In general
You should work with your system based on your needs and not based on set in stone rules like
"Micro Service A should never call Micro Service B".
I will give you an example why:
Example:
Lets say you have "micro-service A" and "micro-service B". Your "micro-service B" is consuming events which "micro-service A" publishes through Kafka. "Micro-service B" when consuming the events is storing some relevant "External" data in its own database(duplicating it).
This is common approach not to call the "micro-service A" each time you need some of its data. This is common for example
if "micro-service A" is some service having the system configuration settings or similar.
Lets say you have scenario of disaster where your database and all the data from your "micro-service B" is destroyed or corrupted.
In order to solve the problem you could just restore your backup and apply the apply latest events from lets say last 1h where
your "micro-service B" was down and solve the problem(If your event handling is implemented to be Idempotent). All good in this case.
On the other hand if you have a system running for a while on production. After some point you develop "micro-service C" and decide
to deploy it to production. It turns out that you need some data that "micro-service A" produces. You need that data on your "micro-service C"
as External data similar as you had it with "micro-service B". How do you get that data?
You consume all the events from "micro-service A"? In ideal world you would keep all the events in Kafka forever. In this case you would
just subscribe for events and apply all of them to save all the data you need in "micro-service C".
In reality you need to set some Retention Period to your Kafka for lets say 5 days. If you have a system running longer then 5 days you can not recreate your data from events.
In this case you need to call the service directly with Command/Query and populate the "micro-service C" database.
This is just one edge case example for which you will need to have a direct call.
Summary:
There are many other examples where this approach is valid as well.
Very often you will for example need to call another micro-service synchronously and you will want to wait for the response(depending of your business scenario). The best way to do this is calling another micro-service directly with a Command/Query.