-
Notifications
You must be signed in to change notification settings - Fork 312
Description
Currently, the JSON-RPC server is versioned via semver and exposed via the version JSON-RPC method. While this approach works in terms of allowing callers to detect changes, it often leads to compatibility issues and headaches during transition periods while development continues between release versions.
For example, consider when the latest release of dcrd has a major JSON-RPC server version of 6, but then during development leading up the next release, it is bumped to 7. At that point, any consumers, such as dcrwallet, dcrdata, dcrdex, etc, can no longer be used with the current development version of dcrd due to the API incompatibilities. While it is, of course, expected that consumers will necessarily need to be updated for any API changes, the hard switch without any type of deprecation period is not ideal.
I believe a good solution to this is to introduce versioned endpoints to the JSON-RPC API instead of using a single semver for the server. For example, the websocket endpoint might be: wss://127.0.0.1:9109/v2/ws, wss://127.0.0.1:9109/v3/ws, etc. Then, whenever a breaking change to the API is introduced, it is done so under a new endpoint.
In order to avoid having to maintain old endpoints forever, whenever a new endpoint is introduced, the old version should be deprecated but still made available for at least one additional full release cycle of the software. This would mean JSON-RPC endpoints follow the standard approach of supporting the most recent version and the version prior to it and thus ensures consumers have ample time to seamlessly transition to newer endpoints before the older endpoint is removed.
It should be noted that this will require a bit more work when introducing breaking API changes, but it will provide a much more stable API for consumers which I think is important given consumers are really the entire reason for having an RPC API to begin with.
The two main approaches I think would be reasonable are:
- Provide a single versioned endpoint for the entire API; or
- Provide an individual versioned endpoint for each method
Both of these approaches have pros and cons and should be analyzed further in terms cost vs benefit prior to making any concrete decisions. Nevertheless, I wanted to get this documented and get the ball rolling so that it can hopefully land in the dcrd release after the upcoming 1.7.0 release.