软件开发过程当中,经常会须要变动之前的接口,添加或删除接口请求字段,接口字段校验、甚至是变动请求/返回字段名称,若是强制要求全部客户端跟着一块儿升级代价太大。若是接口从一开始就考虑到了版本的设计,那么作到平滑升级就很容易了。git
以@RequestMapping("/api")controller为例:github
优势:能够作到大版本切换,路由下的全部接口同时更新web
缺点:实际中每每不会涉及不少接口同时升级,而且每每难以控制不一样接口的版本(版本管理容易混乱)spring
/** * http://localhost:8090/api/v1/getUser/111 * {"userId":111,"userName":"小明"} * * @param userId * @return */ @RequestMapping(value = "/v1/getUser/{userId}") public GetUserV1Response getUserInfoV1(@PathVariable("userId") Integer userId) { return new GetUserV1Response(userId, "小明"); }
能够单独控制,注意version不存在和乱传值的处理json
/** * http://localhost:8090/api/getUser/111?version=v1 * {"userId":111,"userName":"小明"} * <p> * http://localhost:8090/api/getUser/111?version=v2 * {"userId":111,"userName":"小明","notes":"version 2"} * * @param userId * @return */ @RequestMapping(value = "/getUser/{userId}") public Object getUserInfo(@PathVariable("userId") Integer userId, @RequestParam("version") String version) { if ("v1".equals(version)) { return new GetUserV1Response(userId, "小明"); } return new GetUserV2Response(userId, "小明", "version 2"); }
以@RequestMapping("/api2")controller为例:api
header设置在Controller或Action上均可以,设置在Controller上,控制全部Action的版本,设置在Action上,单独控制一个Action的版本springboot
@RestController @RequestMapping(value = "/api2") public class ApiVersionHeaderDemoController { @Autowired private HttpServletRequest request; //request header @RequestMapping(value = "/getUserById/{userId}", headers = "version=v2") public Object getUserInfo(@PathVariable("userId") Integer userId) {return new GetUserV2Response(userId, "小明", "version 2"); } }
对应版本:restful
不支持的版本:app
利用自定义请求的Content-Type来控制版本:框架
/** * 请求的是 application/vnd.apiversioncontrol.v1+json * 返回的是 application/json;charset=UTF-8 * v1 是api版本 * * @param userId * @return */ @RequestMapping(value = "/getUserById/{userId}", consumes = "application/vnd.apiversioncontrol.v1+json") public Object getUserInfoV11(@PathVariable("userId") Integer userId) { return new GetUserV2Response(userId, "小明", "version 2"); }
返回的是Content-Type:application/json;charset=UTF-8(不指定produces,默认是application/json;charset=UTF-8)
同时指定request和response的Content-Type为:application/vnd.apiversioncontrol.v2+json
/** * 请求、返回Content-Type都是 application/vnd.apiversioncontrol.v1+json * v1 :为api版本 * * @param userId * @return */ @RequestMapping(value = "/getUserById/{userId}", consumes = "application/vnd.apiversioncontrol.v2+json", produces = "application/vnd.apiversioncontrol.v2+json") public Object getUserInfoV12(@PathVariable("userId") Integer userId) { return new GetUserV2Response(userId, "小明", "version 2"); }
同时指定request和response的Content-Type为:application/vnd.apiversioncontrol+json;version=v2
/** * 请求、返回Content-Type都是 application/vnd.apiversioncontrol+json;version=v2 * v2 :为api版本 * * @param userId * @return */ @RequestMapping(value = "/getUserById/{userId}", consumes = "application/vnd.apiversioncontrol+json;version=v2", produces = "application/vnd.apiversioncontrol+json;version=v2") public Object getUserInfoV2(@PathVariable("userId") Integer userId) { return new GetUserV2Response(userId, "小明", "version 2"); }
注解来实现:SpingMVC框架实现restfull接口的版本控制