Hey everyone,
I'm trying to understand what the best practices are around versioning for GRPC. There have been a number of strategies employed in the world of RESTful APIs (like versioning headers), and protobuf's are typically argued as being cross-compatible as long as you make changes in a reasonable set of ways. I'm however struggling to understand how it would be possible to allow cross-version compatibility when it comes to new features being added to existing RPCs whilst still dealing with older servers.
For instance, if I have an RPC method that permits searching a data-set, and I later want to add a field which allows you to search with a higher degree of data consistency. If a newer client were to send this field, a potentially older server might ignore this and not apply the new semantics, leading to the results being silently incorrect.
I see a couple of mechanism that could solve this, namely:
a. Have servers reject fields they do not understand. This seems like a bad choice since it precludes other kinds of non-breaking changes.
b. Use some form versioning header such that using the new fields requires you to advertise being a 'new client' and old servers would reject those requests. This seems like unneccessary overhead.
c. Add a new major version of the service (ie: adding my_service.v2 in addition to my_service.v1). This seems frustrating to deal with, since you have to duplicate the entire surface area of the API simply to iterate on a specific method.
d. Add versions to individual RPCs (ie: adding MyQueryV2() in addition to MyQuery()). I don't really see any examples of this 'in the wild' though, and seems like a messy solution.
None of these solutions seem great or particularly often used, so I'm hoping there might be some beautiful and elegant solution I'm missing :)
Thanks, Brett