You don't have to. The producers of the microservice also produces an adapter. The adapter looks like a regular local service, but it implements the code as a REST request to another microservice. This was you get you type-safety. Generally you structure the code as
Proj:
|-proj-api
|-proj-client
|-proj-service
Both proj-client and proj-service consume/depend-on proj-api so they are in sync of what is going on.
Now, you can switch the implementation of the service to gRPC if you wanted with full source compatibility. Or move it locally.
Proj:
|-proj-api
|-proj-client
|-proj-service
Both proj-client and proj-service consume/depend-on proj-api so they are in sync of what is going on.
Now, you can switch the implementation of the service to gRPC if you wanted with full source compatibility. Or move it locally.