美文网首页
RESTful API如何进行版本控制

RESTful API如何进行版本控制

作者: JAVA日知录 | 来源:发表于2021-01-26 09:17 被阅读0次

    本文将帮助您理解为什么需要版本控制,以及如何对REST API进行版本控制。我们将讨论4种版本控制的方法,并比较不同的方法。

    您将学到

    • 为什么我们需要对RESTful API 进行版本控制?
    • 可用的版本控制有哪些?
    • 如何实现基于 Restful 的版本控制?

    为什么我们需要对RESTful API进行版本化

    最好的版本控制方法是不进行版本控制。只要不需要版本控制,就不要版本控制。

    构建向后兼容的服务,以便尽可能避免版本控制!

    然而,在许多情况下我们都需要进行版本控制,然我们看看下面具体的例子:

    最初,你有个这个版本的Student服务,返回数据如下:

    {
      "name": "Bob Charlie"
    }
    

    后来,您希望将学生的名字拆分,因此创建了这个版本的服务。

    {
      "name": {
        "firstName": "Bob",
        "lastName": "Charlie"
      }
    }
    

    您可以从同一个服务支持这两个请求,但是随着每个版本的需求多样化,它会变得越来越复杂。

    在这种情况下,版本控制就成必不可少,强制性的了。

    接下来让我们创建一个简单的SpringBoot的maven项目,并理解对 RESTful 服务进行版本控制的4种不同方法。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    

    几个用于实现版本控制的Bean

    第一个版本的 Bean

    @Data
    @AllArgsConstructor
    public class StudentV1 {
        private String name;
    }
    

    第二个版本的 Bean

    @Data
    public class StudentV2 {
        private Name name;
    }
    

    StudentV2使用的Name实体

    @Data
    @AllArgsConstructor
    public class Name {
        private String firstName;
        private String lastName;
    }
    

    Restful 版本控制的方法

    我们希望创建两个版本的服务,一个返回 StudentV1,另一个返回 StudentV2。

    让我们来看看创建相同服务版本的4种不同方法。

    通过 URI 进行版本控制

    @RestController
    public class StudentUriController {
    
        @GetMapping("v1/student")
        public StudentV1 studentV1() {
            return new StudentV1("javadaily");
        }
    
        @GetMapping("v2/student")
        public StudentV2 studentV2() {
            return new StudentV2(new Name("javadaily", "JAVA日知录"));
        }
    
    }
    

    请求:http://localhost:8080/v1/student

    响应:{"name":"javadaily"}

    请求:http://localhost:8080/v2/student

    响应:{"name":{"firstName":"javadaily","lastName":"JAVA日知录"}}

    通过请求参数进行版本控制

    版本控制的第二种方法是使用请求参数来区分版本。请求示例如下所示:

    • http://localhost:8080/student/param?version=1
    • http://localhost:8080/student/param?version=2

    实现方式如下:

    @RestController
    public class StudentParmController {
    
        @GetMapping(value="/student/param",params = "version=1")
        public StudentV1 studentV1() {
            return new StudentV1("javadaily");
        }
    
        @GetMapping(value="/student/param",params = "version=2")
        public StudentV2 studentV2() {
            return new StudentV2(new Name("javadaily", "JAVA日知录"));
        }
    }
    

    请求:http://localhost:8080/student/param?version=1

    响应:{"name":"javadaily"}

    请求:http://localhost:8080/student/param?version=2

    响应:{"name":{"firstName":"javadaily","lastName":"JAVA日知录"}}

    通过自定义Header进行版本控制

    版本控制的第三种方法是使用请求头来区分版本,请求示例如下:

    • http://localhost:8080/student/header

      • headers=[X-API-VERSION=1]
    • http://localhost:8080/student/header

      • headers=[X-API-VERSION=2]

    实现方式如下所示:

    @RestController
    public class StudentHeaderController {
    
        @GetMapping(value="/student/header",headers = "X-API-VERSION=1")
        public StudentV1 studentV1() {
            return new StudentV1("javadaily");
        }
    
        @GetMapping(value="/student/header",headers = "X-API-VERSION=2")
        public StudentV2 studentV2() {
            return new StudentV2(new Name("javadaily", "JAVA日知录"));
        }
    }
    

    下图展示了我们如何使用Postman执行带有请求头的Get请求方法。

    请求:http://localhost:8080/student/header header:X-API-VERSION = 1

    image.png

    请求:http://localhost:8080/student/header header:X-API-VERSION = 2

    image.png

    通过媒体类型进行版本控制

    最后一种版本控制方法是在请求中使用Accept Header,请求示例如下:

    • http://localhost:8080/student/produce

      • headers=[Accept=application/api-v1+json]
    • http://localhost:8080/student/produce

      • headers=[Accept=application/api-v2+json]

    实现方式如下:

    @RestController
    public class StudentProduceController {
    
        @GetMapping(value="/student/produce",produces = "application/api-v1+json")
        public StudentV1 studentV1() {
            return new StudentV1("javadaily");
        }
    
        @GetMapping(value="/student/produce",produces = "application/api-v2+json")
        public StudentV2 studentV2() {
            return new StudentV2(new Name("javadaily", "JAVA日知录"));
        }
    }
    

    下图展示了我们如何使用Postman执行带有请求Accept的Get方法。

    请求:http://localhost:8080/student/produce header:Accept = application/api-v1+json

    image.png

    请求:http://localhost:8080/student/produce header:Accept = application/api-v2+json

    image.png

    影响版本选择的因素

    以下因素影响版本控制的选择

    • URI 污染 - URL版本和请求参数版本控制会污染URI空间。
    • 滥用请求头 - Accept 请求头并不是为版本控制而设计的。
    • 缓存 - 如果你使用基于头的版本控制,我们不能仅仅基于URL缓存,你需要考虑特定的请求头。
    • 是否能在浏览器直接执行 ? - 如果您有非技术消费者,那么基于URL的版本将更容易使用,因为它们可以直接在浏览器上执行。
    • API文档 - 如何让文档生成理解两个不同的url是同一服务的版本?

    事实上,并没有完美的版本控制解决方案,你需要根据项目实际情况进行选择。

    下面列表展示了主要API提供商使用的不同版本控制方法:

    • 媒体类型的版本控制

      • Github
    • 自定义Header

      • Microsoft
    • URI路径

      • Twitter,百度,知乎
    • 请求参数控制

      • Amazon

    相关文章

      网友评论

          本文标题:RESTful API如何进行版本控制

          本文链接:https://www.haomeiwen.com/subject/evawzktx.html