📅  最后修改于: 2021-01-11 06:04:22             🧑  作者: Mango
版本控制是API最重要和最困难的部分,因为它需要向后兼容API。确定更改后,版本控制可帮助我们更快地迭代。我们应该始终对Web API进行版本控制。
考虑一个场景,其中我们有一个已启动(状态)并且正在运行的Web API。用户正在使用该API。现在,我们想在Web API中添加更多功能,但希望保持现有功能不变。可能有少数用户仍想使用旧的API,而其他用户想要具有新功能或扩展功能的API的新版本。这是Web API版本化存在的场景。
当我们对Web API进行重大更改时,我们应该对API进行版本升级。重大更改包括:
重大更改应始终导致API或内容响应类型的主版本号更改。
不间断的更改(添加新点或新的响应参数)不需要更改主版本号。但是,跟踪次要版本的API可能会有所帮助。
最常用的方法分为三类:
URI版本控制是最直接的方法。它在URL中指定为查询字符串。它违反了URI应该引用唯一资源的原则。还保证您在更新版本时会中断客户端集成。 Twitter使用URI版本控制。
例
http://api.demo.com/v1
http://apiv1.demo.com
版本不需要是数字,也不需要使用v [x]语法指定。备选方案包括日期,项目名称,季节或其他有意义的标识符,这些标识符足以随着版本的更改而更改。
自定义标头允许我们保留我们的URL。它与现有Accept标头实现的内容协商行为重复。版本信息是在请求标题中指定的,无需更改URL。 Microsoft使用请求标头版本控制。用户无法在普通浏览器(chrome)中访问请求标头版本。我们需要一个特殊的插件才能在浏览器中访问它们。
例
接受版本:v1
接受版本:v2< p="">
Accept标头定义媒体类型和字符编码。我们还可以通过接受标头传递Web API的版本信息,而无需更改URL。也称为媒体类型版本控制或内容协商或接受标头。 Github使用accept标头版本控制。用户无法在普通浏览器(chrome)中访问接受标头版本控制。我们需要一个特殊的插件才能在浏览器中访问它们。
例
接受:application / vnd.demo.v1 + json接受:application / vnd.demo + json; version = 1.0
让我们看看如何在项目中实现版本控制。
第1步:创建与包com.javatpoint.server.main.versioning名称PersonV1.java类。 PersonV1表示API的第一个版本。 API的初始版本具有名称变量。
PersonV1.java
package com.javatpoint.server.main.versioning;
public class PersonV1
{
private String name;
}
步骤2:经过一段时间,我们认识到需要分别使用名字和姓氏。因此,我们创建了一个名为Person2.java的类。它表示API的第二个版本。
PersonV2.java
package com.javatpoint.server.main.versioning;
public class PersonV2
{
private Name name;
}
步骤3:创建一个名称为Name.java的类,该类分别具有两个变量firstName和lastName。
名称.java
package com.javatpoint.server.main.versioning;
public class Name
{
private String firstName;
private String lastName;
}
旧版本仍返回全名,第二个版本分别返回firstName和lastName。现在,我们需要创建同一服务的两个不同版本。
让我们看看如何为同一服务创建两个不同版本,以及该服务存在哪些不同版本。
步骤4:在Name.java文件中,生成Getter和Setter,使用Fields生成构造函数。创建类Name的无参数构造函数。
名称.java
package com.javatpoint.server.main.versioning;
public class Name
{
private String firstName;
private String lastName;
//no argument constructor
public Name()
{
}
public Name(String firstName, String lastName)
{
super();
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
}
步骤5:打开PersonV1.java类。生成Getter和Setter,使用Fields生成构造函数。创建类PersonV1.java的无参数构造函数。
PersonV1.java
package com.javatpoint.server.main.versioning;
public class PersonV1
{
private String name;
//no argument constructor
public PersonV1()
{
super();
}
public PersonV1(String name)
{
super();
this.name = name;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
步骤6:打开PersonV2.java。生成Getter和Setter,使用Fields生成构造函数。创建类PersonV2.java的无参数构造函数。
PersonV2.java
package com.javatpoint.server.main.versioning;
public class PersonV2
{
private Name name;
public PersonV2()
{
super();
}
public PersonV2(Name name)
{
super();
this.name = name;
}
public Name getName()
{
return name;
}
public void setName(Name name)
{
this.name = name;
}
}
现在我们需要创建一个服务。
步骤7:创建一个名为PersonVersioningController.java的类。为不同的版本创建两个方法,并将它们映射到不同的URI。
PersonVersioningController.java
package com.javatpoint.server.main.versioning;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
@RestController
public class PersonVersoningController
{
//this method is for the first version that returns the entire name
@GetMapping("v1/person")
public PersonV1 personv1()
{
return new PersonV1("Tom Cruise");
}
//this method is for the second version that returns firstName and lastName separately
@GetMapping("v2/person")
public PersonV2 personv2()
{
return new PersonV2(new Name("Tom", "Cruise"));
}
}
步骤8:打开邮递员,并使用URI http:// localhost:8080 / v1 / person发送GET请求。它返回全名,如下图所示。
将第二个版本的URI更改为http:// localhost:8080 / v2 / person。它将分别返回firstName和lastName,如下图所示。
实现版本控制的另一种方法是使用request参数。 Amazon使用请求参数版本控制。打开PersonVersioningController.java并进行以下更改:
两种方法都具有相同的get映射,因此我们将通过使用value和params属性来区分它们。 value属性包含我们要使用的URI,params属性包含区分版本的参数。
PersonVersoningController.java
package com.javatpoint.server.main.versioning;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PersonVersoningController
{
//this method is for first version that returns the entire name
@GetMapping(value="/person/param", params="version=1")
public PersonV1 personV1()
{
return new PersonV1("Tom Cruise");
}
//this method is for second version that returns firstName and lastName separately
@GetMapping(value="/person/param", params="version=2")
public PersonV2 personV2()
{
return new PersonV2(new Name("Tom", "Cruise"));
}
}
现在,移至Postman并使用URI http:// localhost:8080 / person / param?version = 1发送GET请求。它返回全名,如下图所示。
再次,使用URI http:// localhost:8080 / person / param?version = 2生成GET请求以访问第二个版本。它将分别返回firstName和lastName,如下图所示。
还有另一个选项可以使用请求标头进行版本控制。它类似于内容协商。在这种方法中,我们根据请求标头区分服务。
在PersonVersioningController.java中,执行以下操作:
/*---------------using request header--------------*/
//this method is for first version that returns the entire name
@GetMapping(value="/person/header", headers="X-API-Version=1")
public PersonV1 headerV1()
{
return new PersonV1("Tom Cruise");
}
//this method is for second version that returns firstName and lastName separately
@GetMapping(value="/person/header", headers="X-API-Version=2")
public PersonV2 headerV2()
{
return new PersonV2(new Name("Tom", "Cruise"));
}
打开邮递员:
它返回名称全名。
让我们发送版本2的GET请求。为此,我们需要在Headers选项卡下将值从1更改为2。它分别返回firstName和lastName。
版本控制中使用的另一种方法是“接受标头”。也称为内容协商或接受版本控制。在此方法中,我们使用称为Produce的属性。它表示我们为特定服务生成什么样的输出。
在PersonVersioningController.java文件中,执行以下操作:
/*---------------using accept header--------------*/
//this method is for first version that returns the entire name
@GetMapping(value="/person/produces", produces="application/vnd.company.app-v1+json")
public PersonV1 producesV1()
{
return new PersonV1("Tom Cruise");
}
//this method is for second version that returns firstName and lastName separately
@GetMapping(value="/person/produces", produces="application/vnd.company.app-v2+json")
public PersonV2 producesV2()
{
return new PersonV2(new Name("Tom", "Cruise"));
}
打开邮递员:
它返回全名。
让我们发送版本2的GET请求。为此,我们需要将值从Value:application / vnd.company.app-v1 + json更改为Value:application / vnd.company.app-v2 + json 。
它分别返回firstName和lastName。
接受版本:v2<>