ฉันค้นหาวิธีจัดการเวอร์ชัน REST API โดยใช้ Spring 3.2.x แต่ฉันไม่พบสิ่งที่ดูแลรักษาง่าย ฉันจะอธิบายปัญหาที่ฉันมีก่อนจากนั้นวิธีแก้ปัญหา ... แต่ฉันสงสัยว่าฉันกำลังประดิษฐ์วงล้อขึ้นมาใหม่ที่นี่
ฉันต้องการจัดการเวอร์ชันโดยใช้ส่วนหัว Accept และตัวอย่างเช่นหากคำขอมีส่วนหัว Accept application/vnd.company.app-1.1+json
ฉันต้องการให้ MVC ส่งต่อไปยังวิธีการที่จัดการเวอร์ชันนี้ และเนื่องจากไม่ใช่วิธีการทั้งหมดใน API ที่เปลี่ยนแปลงในรุ่นเดียวกันฉันจึงไม่ต้องการไปที่คอนโทรลเลอร์แต่ละตัวของฉันและเปลี่ยนแปลงอะไรสำหรับตัวจัดการที่ไม่มีการเปลี่ยนแปลงระหว่างเวอร์ชัน ฉันไม่ต้องการให้ตรรกะในการคิดว่าจะใช้เวอร์ชันใดในคอนโทรลเลอร์ด้วยตัวเอง (โดยใช้ตัวระบุตำแหน่งบริการ) เนื่องจาก Spring กำลังค้นพบวิธีการเรียกใช้แล้ว
ดังนั้นจึงใช้ API ที่มีเวอร์ชัน 1.0 ถึง 1.8 ซึ่งมีการแนะนำตัวจัดการในเวอร์ชัน 1.0 และแก้ไขใน v1.7 ฉันต้องการจัดการสิ่งนี้ด้วยวิธีต่อไปนี้ ลองนึกภาพว่าโค้ดนั้นอยู่ในคอนโทรลเลอร์และมีโค้ดบางตัวที่สามารถแยกเวอร์ชันออกจากส่วนหัวได้ (ต่อไปนี้ไม่ถูกต้องในฤดูใบไม้ผลิ)
@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;
}
สิ่งนี้ไม่สามารถทำได้ในฤดูใบไม้ผลิเนื่องจากทั้ง 2 วิธีมีRequestMapping
คำอธิบายประกอบเหมือนกันและ Spring ไม่สามารถโหลดได้ แนวคิดคือVersionRange
คำอธิบายประกอบสามารถกำหนดช่วงเวอร์ชันเปิดหรือปิดได้ วิธีแรกใช้ได้ตั้งแต่เวอร์ชัน 1.0 ถึง 1.6 ในขณะที่วิธีที่สองสำหรับเวอร์ชัน 1.7 เป็นต้นไป (รวมถึงเวอร์ชันล่าสุด 1.8) ฉันรู้ว่าแนวทางนี้พังทลายหากมีคนตัดสินใจที่จะส่งผ่านเวอร์ชัน 99.99 แต่นั่นเป็นสิ่งที่ฉันยินดีที่จะอยู่ด้วย
ตอนนี้เนื่องจากข้างต้นเป็นไปไม่ได้หากไม่มีการปรับปรุงใหม่อย่างจริงจังเกี่ยวกับวิธีการทำงานของสปริงฉันจึงคิดที่จะแก้ไขด้วยวิธีที่ตัวจัดการจับคู่กับคำขอโดยเฉพาะอย่างยิ่งการเขียนของฉันเองProducesRequestCondition
และมีช่วงเวอร์ชันอยู่ที่นั่น ตัวอย่างเช่น
รหัส:
@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;
}
ด้วยวิธีนี้ฉันสามารถกำหนดช่วงเวอร์ชันปิดหรือเปิดที่กำหนดไว้ในส่วนการสร้างของคำอธิบายประกอบ ผมทำงานในการแก้ปัญหานี้ตอนนี้มีปัญหาที่ฉันยังคงมีการแทนที่บางชั้นเรียนหลักฤดูใบไม้ผลิ MVC ( RequestMappingInfoHandlerMapping
, RequestMappingHandlerMapping
และRequestMappingInfo
) ซึ่งผมไม่ชอบเพราะมันหมายถึงการทำงานพิเศษทุกครั้งที่ผมตัดสินใจที่จะอัพเกรดเป็นรุ่นที่ใหม่กว่า ฤดูใบไม้ผลิ
ฉันจะขอบคุณทุกความคิด ... และโดยเฉพาะอย่างยิ่งข้อเสนอแนะใด ๆ ให้ทำสิ่งนี้ด้วยวิธีที่ง่ายกว่าและง่ายต่อการดูแล
แก้ไข
การเพิ่มค่าหัว หากต้องการรับรางวัลโปรดตอบคำถามด้านบนโดยไม่แนะนำให้มีตรรกะนี้ในตัวควบคุม Spring มีตรรกะมากมายในการเลือกวิธีการควบคุมที่จะเรียกใช้และฉันต้องการที่จะทำอย่างนั้น
แก้ไข 2
ฉันได้แบ่งปัน POC ดั้งเดิม (พร้อมการปรับปรุงบางอย่าง) ใน github: https://github.com/augusto/restVersioning
produces={"application/json-1.0", "application/json-1.1"}
ฯลฯ