springboot實現接口版本控制(一)


一、接口版本控制目的:

 1.1 保證減少停服務升級(減少升級影響用戶的使用,這里只涉及到接口層,其實還要考慮數據層的版本控制,比如:版本間要雙寫、字段不能刪除等)
 1.2 版本向后兼容

二、接口版本控制的同種做法:

  2.1 在URI中標記版本  https://xxx.com/api/v3/list  【我們今天講的是這種】

  2.2 用參數的形式傳遞版本號:https://xxx.com/api/list?version=3.0

  2.3 將版本號放到request header里:api-version:v1

  2.4 通過token來判斷版本號: https://xxx.com/api/list?token=5782b5e0512c7d47345d10af413b3d28   // 服務端token處理器處理 ------> 確定請求API的內部版本 -----> 執行具體API ------>返回結果

三、實現:【sprinbboot+annotation+spring configuration+mvc】

3.1 自定義注解 ApiVersion.java

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface ApiVersion {
    double value() default 1.0;
}

3.2 版本匹配

public class ApiVersionCondition implements RequestCondition<ApiVersionCondition> {
    private static final Pattern VERSION_PREFIX_PATTERN = Pattern.compile("^\\S+/([1-9][.][0-9])$");
    private double apiVersion;

    public ApiVersionCondition(double apiVersion) {
        this.apiVersion = apiVersion;
    }

    public double getApiVersion() {
        return apiVersion;
    }

    public void setApiVersion(double apiVersion) {
        this.apiVersion = apiVersion;
    }

    @Override
    public ApiVersionCondition combine(ApiVersionCondition other) {
        return new ApiVersionCondition(other.getApiVersion());
    }

    @Override
    public ApiVersionCondition getMatchingCondition(HttpServletRequest httpServletRequest) {

        Matcher matcher = VERSION_PREFIX_PATTERN.matcher(httpServletRequest.getRequestURI());
        if (matcher.find()) {
            Double version = Double.valueOf(matcher.group(1));
            System.out.println("version:" + version + ",this.apiVersion:" + this.apiVersion);
            if (version >= this.apiVersion) {
                return this;
            }
        }
        return null;
    }

    @Override
    public int compareTo(ApiVersionCondition apiVersionCondition, HttpServletRequest httpServletRequest) {
        return Double.compare(apiVersionCondition.getApiVersion(), this.apiVersion);
    }
}

3.3 URL請求映射(帶@ApiVersion注解的走匹配規則)

public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {


    @Override
    protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType,ApiVersion.class);
        return createCondition(apiVersion);
    }

    @Override
    protected RequestCondition<?> getCustomMethodCondition(Method method) {
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(method,ApiVersion.class);
        return  createCondition(apiVersion);
    }

    private RequestCondition<ApiVersionCondition> createCondition(ApiVersion apiVersion) {
        return apiVersion == null ? null : new ApiVersionCondition(apiVersion.value());
    }
}


3.4控制器映射請求定義(URL映射)

@SpringBootConfiguration
public class WebMvcRegistrationsConfig implements WebMvcRegistrations {

    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        return new CustomRequestMappingHandlerMapping();
    }
}

3.5創建控制器


@RestController
public class ImageController {

    @GetMapping("/api/test/{version}")
    @ApiVersion(2.0)
    public String searchTargetImage() {
        return "Hello,Welcome to version 2.0";
    }

    @GetMapping("/api/test/{version}")
    @ApiVersion(1.0)
    public String searchTargetImage2() {
        return "Hello,Welcome to version 1.0";
    }


    @GetMapping("/api/test/{version}")
    @ApiVersion(3.0)
    public String searchTargetImage3() {
        return "Hello,Welcome to version 3.0";
    }

}

3.6執行

localhost:8383/api/test/2.0 => 結果:Hello,Welcome to version 2.0
localhost:8383/api/test/1.0 => 結果:Hello,Welcome to version 1.0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM