接口设计中的版本号

简介: 今天呢,闲来无事,想到了接口设计的版本号的一些知识,特此来简单的说下API接口设计中的Version版本号。
今天呢,闲来无事,想到了接口设计的版本号的一些知识,特此来简单的说下API接口设计中的Version版本号。

我们在接口的日常开发中,肯定都避免不了接口永成不变,那么就会出现接口变更,那么接口变更又是怎么区分的呢?接口变更又会不会对老接口有什么影响或者其他的呢,说了这么多,这就引出了一个版本号的概念,通过给API接口设置不同的版本号就可以达到区分接口的目的,版本号的定义在接口开发中又是百花齐放,我就一个小小的案例来尝试一下简单的用注解的方式定义版本的吧。

市面上目前主要定义版本号的实现主要有三种,第一种是通过接口路径定义的时候直接把Version版本号定义进去,第二种就是通过入参传递版本号以达到访问不同版本的接口,第三种就是设置请求头X-API-VERSION参数实现版本控制。这三种方式中我个人还是倾向于第一种接口路径版本号的方式,主要是这种方式简单直观清晰,并且实现起来也是非常简单的,下面我就第一种接口路径实现版本号的方式简单的用注解实现一下,当然直接写在路径中也可以,但是注解的方式更加显得正规一点。

1.定义版本号注解@ApiVersion

新建一个版本号注解@ApiVersion,用在类上或者方法上都可以,看自己需要。

package cn.youhaveme.version;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiVersion {
    String[] value();
}
2.创建一个ApiVersionMapping继承

RequestMappingHandlerMapping是根据类或方法上的@RequestMapping来生成 RequestMappingInfo的实例。那么我们通过实现registerHandlerMethod方法就可以自定义版本号的实现。通过读取@ApiVersion的版本号拼接上原有路径组成一个新的鞋带版本号的路径就可以实现这种注解式版本。

package cn.youhaveme.version;

import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;

public class ApiVersionMapping extends RequestMappingHandlerMapping {
    @Override
    protected boolean isHandler(Class<?> beanType) {
        return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);
    }

    @Override
    protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
        Class<?> controllerClass = method.getDeclaringClass();
        // Controller的@ApIVersion注解
        ApiVersion apiVersion = AnnotationUtils.findAnnotation(controllerClass, ApiVersion.class);
        // 方法的@ApIVersion注解
        ApiVersion methodAnnotation = AnnotationUtils.findAnnotation(method, ApiVersion.class);
        // 方法上的注解优先级高于类上的注解
        if (methodAnnotation != null) {
            apiVersion = methodAnnotation;
        }
        String[] urlPatterns = apiVersion == null ? new String[0] : apiVersion.value();
        PatternsRequestCondition apiPattern = new PatternsRequestCondition(urlPatterns);
        PatternsRequestCondition oldPattern = mapping.getPatternsCondition();
        PatternsRequestCondition updatedFinalPattern = apiPattern.combine(oldPattern);
        mapping = new RequestMappingInfo(mapping.getName(), updatedFinalPattern, mapping.getMethodsCondition(),
                mapping.getParamsCondition(), mapping.getHeadersCondition(), mapping.getConsumesCondition(),
                mapping.getProducesCondition(), mapping.getCustomCondition());
        super.registerHandlerMethod(handler, method, mapping);
    }
}
3.全局配置

全局配置是让自定义的Mapping生效,正常的如果不配置这个的话自己的Mapping是无法生效的。

package cn.youhaveme.version;

import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Configuration
public class ApiVersionConfig implements WebMvcRegistrations {
    
    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        return new ApiVersionMapping();
    }
}

这样的话就已经实现了版本号的注解开发,如有需要,直接在Controller类上或者方法上使用@ApiVersion("v1")标记版本号即可,怎吗样,还是挺简单的吧。

目录
相关文章
|
运维 前端开发 安全
Java应用结构规范
在Java程序开发中,命名和应用分层无疑是广大后端同胞的两大“痛点”,本文提供一种基于领域模型的轻量级应用分层结构设计,供大家参考。下面按分层结构、分层明细、调用关系、各层规范和通用代码工具展开介绍。
Java应用结构规范
|
1月前
|
安全 测试技术 持续交付
精确版本号的依赖版本范围的优点是什么?
使用精确版本号作为依赖版本范围在项目的稳定性、兼容性、问题排查、安全管理以及合规性等方面都具有显著的优势。在实际项目中,对于一些关键的依赖库或对稳定性要求极高的项目组件,建议优先考虑使用精确版本号来确保项目的可靠运行。
24 1
|
6月前
|
Java 数据处理
接口设计规范
接口设计规范
265 2
|
7月前
|
JSON 监控 测试技术
依赖第三方的接口如何测试?
依赖第三方的接口如何测试?
214 0
|
缓存 运维 jenkins
上线操作规范——基础版本
最近团队成员的上线操作让人头疼。几个特别突出的问题: 1、上线准备不足,设计文档中没有体现、也没有考虑到可能的资源依赖,导致临操作了才想起来做资源申请; 2、暗箱操作... 一再要求上线时需要在群内周知,以便前后端、测试、产品共同配合完成,但依然不加理会,总是要主动询问才回复已操作; 3、发布完成就认为上线完成,有时甚至不做基本的校验...
313 0
|
前端开发 JavaScript API
【从零开始的前端工程化】semver语义化版本规范 🙋🏻‍♂️ 你真的了解版本号嘛 ?
【从零开始的前端工程化】semver语义化版本规范 🙋🏻‍♂️ 你真的了解版本号嘛 ?
460 0
【从零开始的前端工程化】semver语义化版本规范 🙋🏻‍♂️ 你真的了解版本号嘛 ?
|
JavaScript 开发工具 git
规范(二):版本规范和 Changelog
规范(二):版本规范和 Changelog
规范(二):版本规范和 Changelog
rapidio 各版本规范
rapidio 各版本规范
163 0
|
JSON 前端开发 安全
RobotFrameWork接口设计规范
RobotFrameWork接口设计规范
144 0
RobotFrameWork接口设计规范