2

Are there any conventions of how to name Java packages containing classes that consume an external, versioned API?

Let's assume we have a major-minor semantic versioning scheme of a service and we have to implement a consumer that is compatible with and bound to a specific version of that API. What are the best practices to name the packages (and classes)?

Currently, we're using the scheme of: ${service}_${M}_${N} (with M = Major version, N = minor version). For example: com.example.theService_1_0.. But sonarqube is complaining that it does not match conventions. Of course I can just disable this rule, but I wonder if there are any best-practices?

I'm looking for a general approach not only something specific to REST, because I've encountered consumer implementations for WebService, REST and CORBA. And I'm not sure, artifact-versioning (as in maven) works well here, because it relates to the version of the implementation and not the API.

I know there are questions around api versioning, but those are about the producer, not the consumer.

Community
  • 1
  • 1
Gerald Mücke
  • 10,724
  • 2
  • 50
  • 67
  • Doesn't it mean potential unnecessary code re-writes. Everytime the producer change version you need to change your package name and all import statements in all classes using that classes. – 7663233 Mar 20 '17 at 10:15
  • I've seen in some projects (in financial industry) that simply keep them side-by-side (with the cost of duplicated code), and maintain consumers separately, so change to one consumer version impl does not affect another impl. When a new version comes up (which is a matter of years), they start by duplicating existing code. It's basically a shared-nothing approach. It certainly is a pragmatic practice, but I wonder if there are any (better?) alternatives? – Gerald Mücke Mar 20 '17 at 10:20
  • I wouldn't name packages after a target API version. Your project should declare a dependency to a given API version, and you would just version your project with its own versionning number, each time you want to target a different API version (i.e when you change the dependency version).Example : myproject version 1.1.8 uses theapi version 2.3.0 , myProject version 1.2.0 uses theapi version 2.4.6 . – Arnaud Mar 20 '17 at 10:21
  • @Berger, that would work if the API is available as a dependency (i.e. maven) which can be checked. But assume, that is not the case (i.e. http, wsdl, corba/idl). It becomes especially tricky, if you're consuming parts of two API versions in the same application (this is not a hypothetical example, I've seen this in real life) – Gerald Mücke Mar 20 '17 at 10:26
  • I know this is an old thread, but I'm here because I'm trying to figure out how to deal with supporting side-by-side versions of an API. With my use-case, the vendor's API changes approximately quarterly. Sometimes the changes are breaking changes. My app needs to support integration to whichever version a client has in their environment, so I think I need to treat the version as a configuration option and provide some kind of switch to varying underlying logic. Most of the client code can actually be generated, so the code overhead is not a major factor. – Eric H May 10 '21 at 21:52

1 Answers1

1

Yes, Java package names have a strong and ambiguous convention for indicating dependencies’ versions: don’t.

If you change your application to use a new version of an external API, you create a new version of your application. The version number you are looking for is your application’s version number. On many Java projects, dependencies’ versions are management by a Maven configuration file.

In any case, when classes use a particular API version, the class and package names have no business exposing this information, which would violate encapsulation, apart from anything else. These names have a different purpose.

Note that this is no different when you use HTTP/REST APIs or Java APIs. After all, I don’t think you’d name your class TheServiceWithLog4J_12_1_5. I hope not, at least.

You didn’t mention whether you have a requirement to support multiple versions of this external API at the same time. Even if you did, I still wouldn’t recommend exposing the API version number in the package name. Instead, use the package name to indicate why you have two versions, and the important difference.

Peter Hilton
  • 17,211
  • 6
  • 50
  • 75