Tôi đã tìm kiếm cách quản lý các phiên bản API REST bằng Spring 3.2.x, nhưng tôi không tìm thấy bất kỳ thứ gì dễ bảo trì. Đầu tiên tôi sẽ giải thích vấn đề tôi gặp phải, sau đó là giải pháp ... nhưng tôi tự hỏi liệu tôi có đang phát minh lại bánh xe ở đây không.
Tôi muốn quản lý phiên bản dựa trên tiêu đề Chấp nhận và ví dụ: nếu một yêu cầu có tiêu đề Chấp nhận application/vnd.company.app-1.1+json
, tôi muốn Spring MVC chuyển tiếp điều này tới phương thức xử lý phiên bản này. Và vì không phải tất cả các phương thức trong API đều thay đổi trong cùng một bản phát hành, tôi không muốn đi đến từng bộ điều khiển của mình và thay đổi bất kỳ điều gì cho một trình xử lý không thay đổi giữa các phiên bản. Tôi cũng không muốn có logic để tìm ra phiên bản nào sẽ sử dụng trong chính bộ điều khiển (sử dụng bộ định vị dịch vụ) vì Spring đã khám phá ra phương thức nào để gọi.
Vì vậy, đã sử dụng một API với các phiên bản 1.0 đến 1.8 trong đó trình xử lý được giới thiệu trong phiên bản 1.0 và được sửa đổi trong v1.7, tôi muốn xử lý điều này theo cách sau. Hãy tưởng tượng rằng mã bên trong một bộ điều khiển và có một số mã có thể trích xuất phiên bản từ tiêu đề. (Phần sau không hợp lệ trong Spring)
@RequestMapping(...)
@VersionRange(1.0,1.6)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(...) //same Request mapping annotation
@VersionRange(1.7)
@ResponseBody
public Object method2() {
// so something
return object;
}
Điều này không thể xảy ra trong Spring vì 2 phương pháp có cùng RequestMapping
chú thích và Spring không tải được. Ý tưởng là VersionRange
chú thích có thể xác định phạm vi phiên bản mở hoặc đóng. Phương pháp đầu tiên có hiệu lực từ phiên bản 1.0 đến 1.6, trong khi phương pháp thứ hai dành cho phiên bản 1.7 trở đi (bao gồm cả phiên bản 1.8 mới nhất). Tôi biết rằng cách tiếp cận này sẽ bị phá vỡ nếu ai đó quyết định vượt qua phiên bản 99.99, nhưng đó là điều tôi có thể sống cùng.
Bây giờ, vì phần trên không thể thực hiện được nếu không có sự làm lại nghiêm túc về cách hoạt động của Spring, tôi đã nghĩ đến việc mày mò cách xử lý phù hợp với yêu cầu, đặc biệt là viết của riêng tôi ProducesRequestCondition
và có phạm vi phiên bản trong đó. Ví dụ
Mã:
@RequestMapping(..., produces = "application/vnd.company.app-[1.0-1.6]+json)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(..., produces = "application/vnd.company.app-[1.7-]+json)
@ResponseBody
public Object method2() {
// so something
return object;
}
Bằng cách này, tôi có thể xác định phạm vi phiên bản đóng hoặc mở trong phần sản xuất của chú thích. Tôi đang làm việc trên giải pháp này ngay bây giờ, với những vấn đề mà tôi vẫn phải thay thế một số lớp lõi Spring MVC ( RequestMappingInfoHandlerMapping
, RequestMappingHandlerMapping
và RequestMappingInfo
), mà tôi không thích, bởi vì nó có nghĩa là thêm công việc bất cứ khi nào tôi quyết định nâng cấp lên một phiên bản mới hơn của mùa xuân.
Tôi sẽ đánh giá cao bất kỳ suy nghĩ nào ... và đặc biệt, bất kỳ đề xuất nào để thực hiện điều này theo cách đơn giản hơn, dễ duy trì hơn.
Biên tập
Thêm tiền thưởng. Để nhận được tiền thưởng, vui lòng trả lời câu hỏi ở trên mà không đề nghị có logic này trong chính bộ điều khiển. Spring đã có rất nhiều logic để chọn phương thức điều khiển nào sẽ gọi, và tôi muốn dựa trên đó.
Chỉnh sửa 2
Tôi đã chia sẻ POC gốc (với một số cải tiến) trong github: https://github.com/augusto/restVersinstall
produces={"application/json-1.0", "application/json-1.1"}