webapi 版本控制

1、問題

   軟件開發過程當中,經常會須要變動之前的接口,添加或刪除接口請求字段,接口字段校驗、甚至是變動請求/返回字段名稱,若是強制要求全部客戶端跟着一塊兒升級代價太大。若是接口從一開始就考慮到了版本的設計,那麼作到平滑升級就很容易了。git

2、版本控制方式

一、利用url傳入版本

以@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, "小明");
    }

經過參數傳入(POST 或 GET)

能夠單獨控制,注意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");
    }

二、利用request header

以@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

利用自定義請求的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");
    }

 3、註解實現

註解來實現:SpingMVC框架實現restfull接口的版本控制

 

參考:webapi-version-control

相關文章
相關標籤/搜索