简体   繁体   English

Java API 中输入的版本控制

[英]Versioning of input in Java API

I have a Spring Boot API which takes JSON as the input and uses the data to populate an XML which is sent to another application.我有一个 Spring Boot API,它将 JSON 作为输入,并使用数据填充发送到另一个应用程序的 XML。

I'm currently looking at versioning for this.我目前正在为此寻找版本控制。 One approach I'm taking is to add either URI or header based versioning.我采用的一种方法是添加基于 URI 或 header 的版本控制。 I'll most likely go for the header based option by including the version in the Accept header.通过将版本包含在接受 header 中,我很可能将 go 用于基于 header 的选项。

I'm also looking into options for versioning the input data itself.我也在研究对输入数据本身进行版本控制的选项。 The input JSON has changed quite significantly recently and this has caused problems where any updates have had to be coordinated with updates to the client applications.输入 JSON 最近发生了相当大的变化,这导致了任何更新都必须与客户端应用程序的更新相协调的问题。 If possible I want to include some form of versioning so API updates can be released without need to coordinate with client updates.如果可能的话,我想包括某种形式的版本控制,这样就可以发布 API 更新,而无需与客户端更新协调。

An example of changes include the below where the JSON structure was changed from:更改的示例包括以下内容,其中 JSON 结构已更改:

{
  "customer": {
    "dateOfBirth": "01/01/1970",
    "occupation": "TCH",
    "contractDetails": {
        "startDate": "08/12/2022"
    }
}

to:到:

{
  "customer": {
    "personalDetails: {
      "dateOfBirth": "01/01/1970",
      "occupation": "TCH"
    },
    "contractDetails": {
        "startDate": "08/12/2022"
    }
}

In my application I had a Customer model which looked like this:在我的应用程序中,我有一个客户 model,它看起来像这样:

@Data
@AllArgsConstructor(access=AccessLevel.PACKAGE)
@NoArgsConstructor(access=AccessLevel.PACKAGE)
@Builder(toBuilder=true)
public class Customer {
  @NotEmpty 
  private String dateOfBirth;

  @NotNull
  @Pattern(regexp="^[A-Z]{3}", message=INVALID_CODE)
  private String occupation;

  @Valid @NotNull private ContractDetails contractDetails;
}

Has now changed to:现已更改为:

@Data
@AllArgsConstructor(access=AccessLevel.PACKAGE)
@NoArgsConstructor(access=AccessLevel.PACKAGE)
@Builder(toBuilder=true)
public class Customer {
  @Valid @NotNull private PersonalDetails personalDetails;
  @Valid @NotNull private ContractDetails contractDetails;
}


@SuperBuilder(toBuilder=true)
@Data
@AllArgsConstructor(access=AccessLevel.PACKAGE)
@NoArgsConstructor(access=AccessLevel.PACKAGE)
public class PersonalDetails {
  @NotEmpty 
  private String dateOfBirth;

  @NotNull
  @Pattern(regexp="^[A-Z]{3}", message=INVALID_CODE)
  private String occupation;
}

Is there any way I can identify variables or classes with some type of versioning so one client might continue to use the old structure whislt anothe client might use the new structure?有什么方法可以识别具有某种版本控制类型的变量或类,以便一个客户端可能继续使用旧结构而另一个客户端可能使用新结构? Without some means of identifying this the API could quickly accumulate a lot of duplicate code and it may be confusing for anyone to enhance/debug.如果没有某种方法来识别这一点,API 可能会迅速积累大量重复代码,并且任何人都可能难以增强/调试。 Eventually I'd like to include some process for identifying versions that are no longer in use and depricate them.最后,我想包括一些流程,用于识别不再使用的版本并将它们弃用。

There are many methods to version input data in your Spring Boot API. Some choices:在 Spring Boot API 中有多种版本输入数据的方法。一些选择:

Using a version field in the JSON payload: You might send the API a version field.在 JSON 负载中使用版本字段:您可以向 API 发送一个版本字段。 This field would reflect the client's payload structure version.该字段将反映客户端的有效负载结构版本。 The API might then utilise this field to parse and process the payload.然后 API 可能会利用此字段来解析和处理有效负载。

Various endpoints for distinct API versions: You may use different endpoints for different API versions.不同 API 版本的各种端点:您可以为不同的 API 版本使用不同的端点。 For instance, you may have /api/v1/customer and /api/v2/customer, where v1 expects the old payload structure and v2 expects the new.例如,您可能有 /api/v1/customer 和 /api/v2/customer,其中 v1 需要旧的有效负载结构,而 v2 需要新的。

Content negotiation: You may use content negotiation to let customers choose which API version to use.内容协商:您可以使用内容协商让客户选择使用哪个 API 版本。 A version parameter in the Accept header might achieve this. Accept header 中的版本参数可能会实现此目的。 "Accept: application/vnd.myapi.v1+json," for instance.例如,“接受:application/vnd.myapi.v1+json”。

Various package names: You might use different package names for different model class versions.各种 package 名称:您可以为不同的 model class 版本使用不同的 package 名称。 For instance, you may have com.myapi.model.v1.Customer and v2.Customer.例如,您可能有 com.myapi.model.v1.Customer 和 v2.Customer。 This would let you have various class versions without naming problems.这将使您拥有各种 class 版本而不会出现命名问题。

Jackson's @JsonTypeInfo and @JsonSubTypes annotations to define class versions in the class specification. Jackson 的@JsonTypeInfo 和@JsonSubTypes 注解在 class 规范中定义了 class 版本。 The API will utilise the right class version if you indicate the class version.如果您指定 class 版本,则 API 将使用正确的 class 版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM