You should assume that any code you distribute will be around forever and people will not update it. With this in mind, you should plan for backwards compatibility forever and design your APIs appropriately. If you have special knowledge that you can update all clients/ servers (via some sort of auto updating package manager), then you need to at least support all methods until you know for sure all have updated. You can include a user agent string in the headers of your API calls to indicate what version is running.
In general:
- As you said never reuse a field number
- Never change the type of a field. Even if you know what you are doing, don't.
- If you are on proto2, never use required fields. They are more dangerous than you think. They do not stand the test of time
- Don't use or depend on default values.
There are a couple ways of supporting older clients. One way is the union style:
message DoSomethingRequest {
DoItWayOne first = 1;
DoItWayTwo second = 2;
}
When you want to add a third way, just add it in. Servers need to check which way is set and use the appropriate code path. Also all servers will need to be updated before releasing it in the clients.
Always make sure that each client can work with the current server version and the next server version. Serves must work with the current client and the next client. This forms a chain of compatibility that makes rolling out new versions easy and makes rolling back safe!
Hopefully this helps.