Java – Version-postfixed class name for REST api

coding-standardsjavanamingrestspring-mvc

I'm working on a Spring-based REST api that has v1 and v2 variants:

/api/v1/dates
/api/v2/dates

Correspondingly, there are v1 and v2 packages in the code base:

com.company.api.v1
com.company.api.v2

Is it a good practice to postfix class names with version number like below:

  • DatesControllerV1.java (in v1 package)
  • DatesControllerV2.java (in v2 package)

I prefer not postfixing version in the class name as:

  • their package names should tell you about the version already, redundant;
  • I simply don't like numeric character in class name.

However, not postfixing version(ie. same class name but in different packages) will increase the probability of using the wrong class accidentally due to IDE auto-complete/auto-import by careless developers.

I tried looking for a github repo that has similar code base structure and see how they deal with it. But could not find one unfortunately.

I'm wondering which approach do you think is better and the reason. I'm also wondering if there is a better approach(for the current code base setup) than these two?

UPDATE

With the help from Azuaron and CormacMulhall, I realized that I really don't have other options to improve my current situation, given that both the v1 and v2 APIs reside in the same code base and I cannot change this setup.

For those who are seeking for the proper way of doing this(having different versions of APIs), please see Azuaron's answer below.

Best Answer

I must admit, my heart contracted in stress when I read "...there are v1 and v2 packages in the code base..." Typically, versioned APIs are, well, versions of your code, and don't live side-by-side in your codebase.

How I've done it before is forking the repo. V1 sticks around for bug fixes until we can get everyone onto V2, and V2 is where all the new features go. Then in production, you deploy both codebases (either on different servers, or side-by-side), and your URL routing points to the appropriate instance.

This gives you the following benefits:

  1. The only way someone writes code against the wrong API is if they're in the wrong repo (at which point, there's not much else you can do for that programmer).

  2. You don't have to worry about backward compatibility in "shared" non-API classes (utility, service, DAO, what have you).

  3. A deploy of one API does not impact the other.

  4. Honestly? It provides a demonstrable business reason to abandon v1 as soon as possible (you can shut down the old server) that can clearly be explained to non-developers.

The downside is that the codebase is not shared, so changes in one that are "necessary" in the other must be ported. I don't see this as a big deal. It shouldn't happen that much (new features go into v2, not v1, by design), and any changes that truly need to be shared can be extracted into libraries or other services.

Related Topic