เหตุใดจึงเป็นความคิดที่ไม่ดีที่จะแบ่งปันอินเทอร์เฟซระหว่างเซิร์ฟเวอร์และไคลเอนต์


12

ฉันอ่านเอกสารSpring Cloud Netflixเมื่อฉันค้นพบวิธีแชร์อินเทอร์เฟซระหว่างเซิร์ฟเวอร์ HTTP และไคลเอนต์ พวกเขาใช้ตัวอย่างนี้สำหรับ microservices แม้ว่าจะไม่มีเหตุผลว่าทำไมมันถึงขยายไปยังการสื่อสาร HTTP ทั่วไปไม่ได้:

// The shared interface, in a common library
public interface UserService {
    @RequestMapping(method = GET, value = "/users/{id}")
    User getUser(@PathVariable long id);
}

// The controller, on the server
@RestController
public class UserResource implements UserService {
}

// The same interface used for the client
@FeignClient("users")
public interface UserClient extends UserService {
}

สิ่งนี้นิยามอินเตอร์เฟสที่ถูกใช้เป็นทั้งเซิร์ฟเวอร์ (The Spring @RestControllerเปลี่ยนเป็นเซิร์ฟเวอร์ HTTP) และไคลเอ็นต์ (The Feign @FeignClientตั้งค่าสำหรับการใช้ไคลเอ็นต์ HTTP) การใช้งานคลาสเซิร์ฟเวอร์และไคลเอนต์สามารถใช้ในโครงการแยกต่างหาก แต่ยังคงใช้อินเทอร์เฟซเดียวกันเพื่อให้แน่ใจว่าตรงกับชนิด

อย่างไรก็ตามภายใต้ตัวอย่างพวกเขาใส่ข้อแม้ต่อไปนี้:

หมายเหตุ:โดยทั่วไปจะไม่แนะนำให้แชร์อินเตอร์เฟสระหว่างเซิร์ฟเวอร์และไคลเอ็นต์ มันแนะนำการมีเพศสัมพันธ์อย่างแน่นหนาและจริง ๆ แล้วไม่ได้ทำงานกับ Spring MVC ในรูปแบบปัจจุบัน

ตกลงดังนั้นตอนนี้ยังไม่ได้รวมกันเป็นอย่างดี ... แต่ส่วนนั้นเกิดขึ้นหลังจากคำเตือนรหัสการแชร์และการแนะนำการเชื่อมต่อระหว่างเซิร์ฟเวอร์และไคลเอนต์ซึ่งพวกเขาคิดว่าสำคัญกว่า ทำไมพวกเขาคิดว่าเป็นความคิดที่ไม่ดีที่จะแบ่งปันอินเทอร์เฟซด้วยวิธีนี้

หากไม่มีคุณจะสูญเสียความสามารถในการรับประกันว่าเซิร์ฟเวอร์และไคลเอนต์จะส่งข้อมูลซึ่งกันและกันซึ่งพวกเขาสามารถเข้าใจได้ คุณสามารถเพิ่มฟิลด์หนึ่งไปยังอีกฟิลด์หนึ่ง แต่ไม่ใช่ฟิลด์อื่นและค้นพบว่าไม่ตรงกันจนกว่าจะถึงเวลาจริง ในใจของฉันมันไม่ได้แนะนำการมีเพศสัมพันธ์ แต่เพียงเปิดเผยการมีเพศสัมพันธ์ที่มีอยู่แล้ว จำเป็นที่จะต้องทำให้เซิร์ฟเวอร์เป็นอิสระโดยสมบูรณ์มากกว่าความต้องการที่จะให้พวกเขารู้ว่าพวกเขาจะได้รับข้อมูลประเภทใด?


1
การมีเพศสัมพันธ์ที่มีอยู่ในแง่ของข้อมูล / การจัดรูปแบบการจัดการโดยลูกค้า / เซิร์ฟเวอร์จะถูกกำหนดโดยโปรโตคอล - ชิ้นส่วนของเอกสารที่สามารถนำมาใช้เป็นที่ประชุม การมีเพศสัมพันธ์ที่แนะนำโดยการแบ่งปันอินเทอร์เฟซคือการรวบรวมเวลา - พิจารณาสิ่งที่เกิดขึ้นเมื่อมีการเปลี่ยนแปลงอินเทอร์เฟซ (ในลักษณะที่ไม่เข้ากันได้ย้อนหลัง) แต่ลูกค้า / รหัสเซิร์ฟเวอร์ที่ใช้อินเทอร์เฟซนั้น ที่ใช้งานเวลามีเพศสัมพันธ์อาจจะยากที่จะจัดการโดยเฉพาะอย่างยิ่งในระดับ Netflix'
Castaglia

1
ฉันค่อนข้างแน่ใจว่าฉันไม่ได้ใช้งานในระดับของ Netflix :) แต่ถ้าอินเทอร์เฟซเปลี่ยนไปในแบบย้อนกลับ - เข้ากันไม่ได้นี่ไม่เพียงแค่เปลี่ยนข้อผิดพลาดจากการถูกพบในเวลาคอมไพล์ พวกเขาคิดว่ามันตกลงหรือไม่ที่จะให้การเรียกใช้ฟังก์ชั่นบางอย่างล้มเหลวในขณะที่พวกเขาอัพเกรดเซิร์ฟเวอร์ทั้งหมดอย่างช้าๆ?
Ben S

1
อาจเป็นไปได้; ขึ้นอยู่กับรหัสลูกค้า พิจารณาอีกกรณี: เซิร์ฟเวอร์ได้รับการอัพเกรดก่อนและตอนนี้ลูกค้าต้องจัดการกับการโทรที่ล้มเหลว (โดยไม่คาดคิด) ...
Castaglia

1
แค่อยากรู้อยากเห็นด้วยการแบ่งปันอินเทอร์เฟซนี้มัน จำกัด ภาษา / สแต็คที่คุณสามารถสร้างลูกค้าได้หรือไม่?
JeffO

ใช่ - เป็นไฟล์ Java ดังนั้นคุณจะต้องใช้ Java คุณอาจใช้ภาษา JVM อื่นได้ แต่ฉันยังไม่ได้ลอง
Ben S

คำตอบ:


6

เหตุผลที่ระบุไว้ในความคิดเห็นก็คือมันส่งผลในการเชื่อมต่อแพลตฟอร์มลูกค้าของคุณอย่างแน่นหนากับแพลตฟอร์มเซิร์ฟเวอร์ของคุณ นี่หมายความว่าลูกค้าของคุณจำเป็นต้องใช้ภาษา / แพลตฟอร์มที่คุณใช้บนเซิร์ฟเวอร์เพื่อทำความเข้าใจกับสัญญาที่คาดไว้ของเซิร์ฟเวอร์ของคุณ โปรดทราบว่ามีความแตกต่างระหว่างการแบ่งปันรหัสเดียวกัน (สิ่งประดิษฐ์ของภาษา / แพลตฟอร์มเฉพาะ) และการตกลงในสัญญาที่เฉพาะเจาะจง

โครงการหลายแห่งใช้เอกสารแทนสัญญาของพวกเขา ตัวอย่างคำขอและการตอบกลับในรูปแบบที่เป็นกลาง (เช่น JSON) เหนือโปรโตคอลมาตรฐาน (เช่น REST) (ดูที่เอกสาร API ลายทาง ) เนื่องจากเป็นเรื่องที่ไม่สามารถเขียนสัญญาตามโค้ดสำหรับทุกแพลตฟอร์มไคลเอนต์ที่เป็นไปได้ที่คุณอาจต้องการใช้หรืออนุญาต ยังคงใช้เครื่องมืออื่น ๆ การจัดการ API เพื่อกำหนดสัญญาเป็นกลาง

ตัวอย่างการเพิ่มเขตข้อมูลของคุณเป็นข้อกังวลแยกต่างหาก - ตัวอย่างว่าทำไมจึงมีความสำคัญต่อสัญญารุ่น API ให้ลูกค้าใช้เวอร์ชันที่ได้รับการออกแบบ มี API รุ่นใหม่ที่เข้ากันไม่ได้กับรุ่นเก่าและรุ่นเก่า ไคลเอนต์สำหรับเวอร์ชันเก่ายังคงทำงานต่อไปจนกว่าทีมจะได้รับการอัปเดตหรือจนกว่าคุณจะเกษียณเวอร์ชันเก่า ดูการเปลี่ยนแปลงขนาน

การปฏิบัติตามคำเตือน (คำแนะนำโดยนัยใน) ช่วยให้ลูกค้าและเซิร์ฟเวอร์มีวิวัฒนาการในรูปแบบและก้าวที่เหมาะสมสำหรับแต่ละคน หากคุณสามารถรับประกันได้อย่างสมเหตุสมผลว่าเซิร์ฟเวอร์และลูกค้าของคุณจะใช้ภาษา / แพลตฟอร์มเดียวกันร่วมกันและมีวิวัฒนาการในระดับเดียวกันเสมอจากนั้นใช้สิ่งประดิษฐ์รหัสเฉพาะภาษาและแพลตฟอร์มเนื่องจากสัญญาของคุณอาจไม่เป็นเช่นนั้น อย่างไรก็ตามนี่อาจไม่ใช่ความคาดหวังที่สมเหตุสมผลโดยเฉพาะอย่างยิ่งสำหรับโครงการที่กำหนดเป้าหมายเป็น Netflix OSS (สิ่งที่ออกแบบมาเป็นพิเศษสำหรับความสามารถในการขยายระบบคลาวด์และประสิทธิภาพโดยมีความซับซ้อนที่จำเป็นทั้งหมด)


2
ลูกค้าคาดหวังว่าจะใช้อินเทอร์เฟซจริง ๆ หรือไม่ ฉันมักจะเห็นโครงสร้างดังกล่าวเป็นวิธีที่จะทำให้การเขียนลูกค้าง่ายขึ้น หลังจากทั้งหมดคุณยังสามารถเขียนไคลเอนต์ REST ในภาษาอื่น
จิมมี่ต.

1
แน่นอน api จะยังคงมีอยู่กับคำจำกัดความเส้นทางของมันไม่มีอะไรป้องกันการสร้างลูกค้าในภาษาอื่น แต่ตราบใดที่คุณใช้จาวาสามารถใช้อินเทอร์เฟซ
Leonardo Villela
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.