1.Background introduction
When developing Restful interfaces with Spring Boot, due to changes in modules, systems and other businesses, different versions of parameter implementations need to be provided for the same interface (old interfaces are still used by modules or systems and cannot be changed directly, so different versions are required). How to implement multi-version interfaces more elegantly? There are many ways to customize version annotations on the Internet, but I don’t recommend doing so because of hard coding and increased system maintenance costs. Moreover, springboot itself supports multiple versions very well, so there is no need to reinvent the wheel.
2.Code Project
pomx.ml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-demo</artifactId>
<groupId>com.et</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api-version</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
controller
package com.et.api.version.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/users")
public class HelloWorldController {
//@GetMapping(params = "version=1")
//@GetMapping(produces = "application/vnd.company.app-v1+json")
@GetMapping(headers = "API-Version=1")
public Map<String, Object> showHelloWorldone(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld1");
return map;
}
//@GetMapping(params = "version=2")
//@GetMapping(produces = "application/vnd.company.app-v2+json")
@GetMapping(headers = "API-Version=2")
public Map<String, Object> showHelloWorldtwo(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld2");
return map;
}
}
package com.et.api.version.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/v1/users")
public class HelloWorldOneController {
@RequestMapping("/hello")
public Map<String, Object> showHelloWorld(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld1吖");
return map;
}
}
package com.et.api.version.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/v2/users")
public class HelloWorldTwoController {
@RequestMapping("/hello")
public Map<String, Object> showHelloWorld(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld2");
return map;
}
}
DemoApplication.java
package com.et.api.version;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
application.yaml
server:
port: 8088
above it’s just some key codes,for all codes, you can see it in the code repository below
Code Repository
3.Test
1.url path
set multi path on the different class,for example
@RequestMapping("/v1/users")
public class HelloWorldOneController {
}
@RequestMapping("/v2/users")
public class HelloWorldTwoController {
}
2.params detectd
@GetMapping(params = "version=1")
public Map<String, Object> showHelloWorldone(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld1");
return map;
}
@GetMapping(params = "version=2")
public Map<String, Object> showHelloWorldtwo(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld2");
return map;
}
3.header detected
@GetMapping(headers = "API-Version=1")
public Map<String, Object> showHelloWorldone(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld1");
return map;
}
@GetMapping(headers = "API-Version=2")
public Map<String, Object> showHelloWorldtwo(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld2");
return map;
}
4.Media Type detectd
@GetMapping(produces = "application/vnd.company.app-v1+json")
public Map<String, Object> showHelloWorldone(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld1");
return map;
}
@GetMapping(produces = "application/vnd.company.app-v2+json")
public Map<String, Object> showHelloWorldtwo(){
Map<String, Object> map = new HashMap<>();
map.put("msg", "HelloWorld2");
return map;
}