“The fox knows many things, but the hedgehog knows one big thing.” Archilochus said in 700 B.C. Centuries later, Unix was developed using similar philosophy: “Do one thing and do it well.”
Derived on the same principles, microservices aim to deliver specific functionality in an independent repeatable way, but any change to that microservice must not result in breaking other services or consumers that it interacts with. Because microservices often invoke other microservices, each must provide a well-defined contract for deployed versions so that any change in the producer microservice will not break the functionality of its consumer counterparts.
There may also be use cases of rolling back consumer microservices that rely on a previous version of producer service, and that brings the discussion how and when code deprecation be done. Importantly, no service should break the versioned contracts unless there are no more consumers with functionality dependent on that specific producer version.
Contracts must be honored
A good microservice implementation must be backward compatible and honoring service contracts must be high on priority. An ideal approach to accomplish this is to follow blue-green deployment model to deploy new microservice code along-side with existing production version code, and teams can test the new code before making it the default production version. This validation model makes the way to get old contracts out of service once every microservice is tested successfully for desired results.