We use microservices but we do allow services to call services.
All endpoint and data contracts exist separately to services and are used by both the service provider (server) and a consumer so all internal contracts are enforced.
That and a fuck ton of integration testing make it work.
And to be honest I really don't like the architecture. It's much much much better to serve hundreds to thousands of smaller instances of your application than one massive thing divided into lots of services.
This is a ghetto I wish we weren't in to be honest.
I have seen places where it makes sense to call directly to another service, and we violate the message rule sometimes ourselves. But in general I really try to avoid it as when we started we had a lot of it and the interdependencies. With that solution build and deployment became worse then just having a monolithic application, and we were ready to kill each other.
I'd also say, microservices are not for every problem, too many people are applying them to the wrong problems (but that is how we all generally learn limits). And a web/app API is generally not where I'd say deploy microservices, but the backend services for that API would make sense. That is exactly what we built now that we are on version 3 of this architecture. API for us is now a totally different beast than the microservices and the whole solution has become a much more manageable with way less churn and confusion. Not to mention deployments are way easier.
We use microservices but we do allow services to call services.
All endpoint and data contracts exist separately to services and are used by both the service provider (server) and a consumer so all internal contracts are enforced.
That and a fuck ton of integration testing make it work.
And to be honest I really don't like the architecture. It's much much much better to serve hundreds to thousands of smaller instances of your application than one massive thing divided into lots of services.
This is a ghetto I wish we weren't in to be honest.