What are the types of API versioning and How to implement them?
-
Your question is only about the Controller? What's it do? ... Also, this is opinion based, so your question is at risk of being closed – OneCricketeer Apr 22 '18 at 01:07
-
That would be a horrible way to handle versioning. You should have a single code base and version the output accordingly. Have a look at the GSON for versioning. – Raf Apr 22 '18 at 01:07
-
This is going to be opinion-based, but I've preferred grouping by version first (among other things, because those tend to be splittable into separate jars or microservices). – chrylis -cautiouslyoptimistic- Apr 22 '18 at 01:31
-
Please, take a look at how HTML is versioned. That is how REST APIs should handle versioning as well as the media-type is the important thing actually. Any proprietary API that does only exchange generic JSON messages bear the danger of tight coupling in it which is what REST actually tries to fix – Roman Vottner Apr 22 '18 at 02:31
-
what serves me very well is this: http://www.javapractices.com/topic/TopicAction.do?Id=205. The idea is to package not by technical layer, but by business features. – sschrass Apr 22 '18 at 08:58
1 Answers
Just to be clear, since the question is very board hence this answer
is by no means the only
way to achieve project structure and versioning
. There might be many other ways, I am just sharing what I have previously used as it is relevant.
Apparently there are different ways to structure your codebase namely
- Layer-based project structure
- Feature-based project structure
In Layer-based project structure
your code is structured based on what different types of layers i.e. controller, service, etc you have whereas in Feature-based project structure
your code is structured based on features
of your system, read here for more info.
There are lots of resources available online that showcase different kind of package structure and I personally stick with layer-based project structure
because I prefer to organize my codebase based on layers
rather than features.
Project structure
One really easy way to get started with a project skeleton, is to look at some example Spring
webapps. For example, I go to Spring Initializer and select the following
- Project name (i.e. myproj)
- Group name (i.e. com)
- Select the modules (i.e. REST, JPA, etc.)
- Generate
Now, I have a REST-based Spring Boot
project that I can use as a skeleton to customize it as per my layers
. You do not have to use Spring Boot
but, what I am trying to showcase is that Spring Boot
recommended project structure for REST
web service.
I usually have the following layers
- controller
- dao
- service
- model
- dto
- exception
- validator
- util
And so on, here is a screenshot of how the project structure looks like
And the unit test
package structure would look as follow, you can imagine how the rest of the test classes look like.
If you have integration test
or would you refer to it end to end test
in your java application itself then, you would need
src/integ-test/java
src/integ-test/resources
Endpoint versioning
There might be different ways to version endpoints. One approach that I have previously used is GSON's versioning support
and it might or might not work for you but, sharing it here anyway.
If you have noticed in the above screenshot there are the following packages
com.myproj.dto.inbound
com.myproj.dto.outbound
DTO
stands for Data Transfer Object
and as shown above the UserInDTO.java
is a representation of User.java
object that comes in the request and you will be using it with @RequestBody
in the endpoint in your controller. The UserOutDTO.java
is a representation of the User.java
object that goes out. When using DTOs
- You can adopt different naming conventions for what the consumer of the system see and what you use in your model (i.e.
User.java
) - You can
include
andexclude
fields in your outgoing and incomingDTOs
without making unwanted changes to your model/business objects (i.e.User.java
)
Now that you have DTOs and if you are using GSON
then you can use it's Versioning
feature to include
and exclude
fields in the UserOutDTO.java
using annotations such as @Since(1.5)
and @Until(2.3)
. Since GSON
is a serialization/deserialization library or in other words it converts JSON
to Java Object
and vice versa, then it has the ability to include
and exclude
fields before the Object
is converted to JSON
and you can achieve way more with the help of writing serialization and deserialization adapters.
Here is a sample of UserOutDTO.java
and how the fields are versioned to include and exclude after a certain version
public class UserOutDTO {
@Expose
@SerializedName("User id")
private int id;
@Expose
private String firstName;
@Expose
private String lastName;
/*
* This field will become available for all requests coming for version 2.0 onwards. For a request before
* version 2.0 the address field won't be available.
*/
@Expose
@Since(2.0)
private String address;
/*
* This field will become available after version 3.0 an example when you extend your model
*/
@Expose
@Until(3.0)
private String nickname;
//Getters and Setters
}
I hope this help. You can also checkout this question, there are a lot of very helpful answers Package structure for a Java project?

- 7,505
- 1
- 42
- 59