Skip to content

Driver versioning and renaming #84

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 23, 2015
Merged

Driver versioning and renaming #84

merged 3 commits into from
Nov 23, 2015

Conversation

boggle
Copy link
Contributor

@boggle boggle commented Nov 20, 2015

No description provided.

boggle pushed a commit that referenced this pull request Nov 23, 2015
Driver versioning and renaming
@boggle boggle merged commit 194e3c0 into neo4j:master Nov 23, 2015
@boggle boggle deleted the driver-v1 branch November 23, 2015 08:34
@cleishm
Copy link

cleishm commented Nov 23, 2015

I really, really dislike having versioned packages in drivers, and it makes upgrading over major versions more painful as everything changes rather than just the incompatible parts. I'm also struggling to think of other Java drivers that do such. So -1 on this change.

@boggle
Copy link
Contributor Author

boggle commented Nov 23, 2015

How would you do API migration if we ever have to? This is meant as a safety for when we need it. We will be very thankful that that we added this. I don't expect this version number to change before Neo4j 5.0.

@cleishm
Copy link

cleishm commented Dec 2, 2015

@boggle Can you find any other example of a driver that has v1 in the package path? Do we really know more than everyone else?

@technige
Copy link
Contributor

technige commented Dec 2, 2015

The subpackage name explicitly highlights the driver API version implemented. At what point are we claiming to "know more than everyone else"?

@boggle
Copy link
Contributor Author

boggle commented Dec 2, 2015

Yes, we do, chris. From experience.

@lutovich
Copy link
Contributor

lutovich commented Dec 2, 2015

Would we ever want to have more than one driver API version implementation in a single java driver?

@technige
Copy link
Contributor

technige commented Dec 2, 2015

Yes, absolutely. A driver can speak up to four protocol versions. The API are closely bound to the protocol so may also vary.

@boggle
Copy link
Contributor Author

boggle commented Dec 2, 2015

Meanwhile this clearly shows three different ways of putting version numbers into a REST API that are all horribly wrong but still explains why this is the right thing todo:

http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html

Seems spot on to me.

@lutovich
Copy link
Contributor

lutovich commented Dec 2, 2015

@nigelsmall what do you mean by "protocol version"?

@davidegrohmann
Copy link

@boggle Why can't we take the same approach as Cypher here? E.g., we have internal versioned packages for implementing the different protocol versions and only one consistent (non-versioned) public API. Of course you will have settings for picking the correct protocol and version.

I would expect a bump of the driver version (e.g., 1.2 -> 2.0) if we need to change the public API. No?

We could also add support for new protocol versions to older drivers if needed.

@jakewins
Copy link
Contributor

jakewins commented Dec 2, 2015

@davidegrohmann Cypher uses, semantically, the exact same approach we use here: Each "Cypher API" is discretely versioned. It defaults to the latest version, which we can't do since we can't have alias namespaces in Java like we can in cypher (and in Python and JS).

The benefit of this approach is that you can upgrade to a new driver version without having breaking API changes, same as in cypher. A good example of when this is useful is how Netty 4 accidentally did this, when they changed all their namespaces - we tried to upgrade all our Netty usage to Netty 4 wholesale and it was a huge mess, swapping the four separate usages we have of Netty over to the latest API one at a time incrementally was a much easier approach.

This makes things easier on our users, and it makes it easier on us if we want to make breaking changes.

@boggle
Copy link
Contributor Author

boggle commented Dec 2, 2015

As Nigel said, different protocol versions might mandate different (incompatible) APIs. In order to support easy migration in such a scenario, you need a driver that supports both APIs. Barring Java 9 modules (which for us is quite some time away), we can only do this by encoding a version number into package or class names. The only alternative to that would involve messing with class loaders and I think nobody want that.

Quoting Cypher is appropriate here: it does exactly that except that its "API version" may be explicitly given in the statement text.

@boggle
Copy link
Contributor Author

boggle commented Dec 2, 2015

Also not doing this is by far no majority opinion:

I'm sure there are more; I agree that OSGi/Java 9 solves this but this is not available to us and hence we need something in the meantime.

@davidegrohmann
Copy link

@jakewins you are mistaken here about Cypher, they don't have versioned public APIs but only versioned internal implementations.

I don't understand the different protocols -> different APIs argument.

@boggle
Copy link
Contributor Author

boggle commented Dec 2, 2015

@davidegrohmann I think you look at this from the wrong level. The correct analogy for Cypher's public API is the query language version and it makes a difference if one says "CYPHER 1.9" or "CYPHER 2.2", doesn't it?

@davidegrohmann
Copy link

@boggle sure you are right in principle, but in practice with the Cypher approach you can switch version with a setting, with your approach you need to recompile code.

@jakewins
Copy link
Contributor

jakewins commented Dec 2, 2015

@davidegrohmann do you have a suggestion for how to do breaking changes in a way that does not require recompiling?

@davidegrohmann
Copy link

@jakewins what kind of "breaking changes" are we talking about? picking a protocol versions or changing public APIs?

@boggle
Copy link
Contributor Author

boggle commented Dec 2, 2015

@davidegrohmann To be clear, the goal is to be able to support two (possibly entirely different) APIs in one driver version. I don't see how we could support API migration in any other way except by throwing in OSGi.

@davidegrohmann
Copy link

@boggle that sounds a little bit strange but if you don't think there is another way fair enough

@jakewins
Copy link
Contributor

jakewins commented Dec 2, 2015

@davidegrohmann changing public APIs. This is all about being able to deploy a new version of the driver with a breaking api (eg. v2) without forcing all modules in an app to swap. It also technically makes it possible for us to release a major API overhaul without breaking backwards compatibility, since the old API can remain in place, a new one under the versioned package name.

@cleishm
Copy link

cleishm commented Dec 2, 2015

I guess my concern is that a change in the API will force an application to update every single use of anything from the library. Essentially every class, and every method of every class, will be deprecated all at once and a replacement introduced in a different package. And it's not something I've noticed other drivers do, hence my question (for ex: http://netty.io/4.0/api/, https://api.mongodb.org/java/3.2/, etc, have no versions in their package names). Between versions those libraries seem to deprecate some methods & classes and add replacements.

@boggle
Copy link
Contributor Author

boggle commented Dec 2, 2015

Again, the idea is to do the usual deprecation & addition cycles without changing the version number. The version number is in place in case that is just not enough. So it won't get in the way of regular use. It is there for when we might need it, as a last resort. And as Jake pointed out, it is not helpful to have to move your whole app to a new api in one go. Providing a versioning scheme allows clients to move to a radically changed, new API gradually. BTW introducing a new api must not necessary imply immediate complete deprecation of the previous API. We could go slower and live with two apis for some time.

@pgpv
Copy link

pgpv commented Dec 3, 2015

Isn't this why we are only allowed breaking changes in major releases?
If someone wants the old functionality or doesn't want breaking changes, then they don't upgrade.
Keeping old versions around doesn't seem very practical. What if we had the following? Would that make sense?

org.neo4j.graphdb.v1.GraphDatabaseService
org.neo4j.graphdb.v2.GraphDatabaseService
org.neo4j.graphdb.v3.GraphDatabaseService

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants