I have a few questions regarding the versioning in the microservices architecture:
Let's say there are three services - S1, S2, S3
S1 calls S2 and S3 to generate a response R1. Service S2 generates response R2 and service S3 generates response R3.
Supported versions:
S1 - 1.0.0, 1.0.1
S2 - 1.0.0, 1.0.1
S3 - 1.0.0
In the version 1.0.0 for Service S1, the response R1 contains two fields - F1, F2. F1 is derived from response R2 and F2 is derived from response R3.
In the version 1.0.1 for the service S1, the response R1 contains 3 fields - F1, F2 and F3.
And, in the version 1.0.1 of the service S2, there is a new field added which is used to derive the F3 field for the response R1.
To summarize:
S1 -> R1 (F1, F2) - version 1.0.0
S1 -> R1 (F1, F2, F3) - version 1.0.1
S2 -> R2
S3 -> R3
How should I be writing the code in the service S1 such that it makes call to service S2 version 1.0.1 when the version specified by the consumer of the service S1 species the version as 1.0.1 and it makes the call to service S2 version 1.0.0 when the version specified by the consumer of the service S1 species the version as 1.0.0?
Another Scenario:
S1 -> R1 (F1, F2) - version 1.0.0 and 1.0.1
S2 -> R2 (F3, F4) - version 1.0.0
S2 -> R2 (F3, F5) - version 1.0.1
S3 -> R3 (F6) - version 1.0.0
F1 is derived from R2 and F2 is derived from R3.
I am looking for some clean way of managing this which is extensible as well as maintainable. Majority of the solutions talk about the versioning strategies like versions in the URLs or in the headers, but not about the design patterns governing the internal implementations.
Let's assume, that service S1 has a controller layer and then a service layer. The calls to other services are made in the service layer.
I am representing a case of backward compatible changes/contract for service S1. For incompatible changes, I can create a version specific implementation in the service layer.