การแชร์วัตถุ DTO ระหว่างไมโครไซต์


15

TL; DR - การใช้ไลบรารี POJO ร่วมกันระหว่างบริการต่าง ๆ เป็นเรื่องปกติไหม

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

ในกรณีของฉัน - ฉันพิจารณาบริการที่สร้างวัตถุของข้อมูล สมมติว่าวัตถุนี้เป็นสัตว์เลี้ยง มันไม่ใช่เอนทิตีของฐานข้อมูล แต่เป็น POJO ที่แสดงถึงข้อมูลพื้นฐานโดยนัย POJO นี้เป็นสิ่งที่ API ได้กำหนดไว้ สมมติว่า: สัตว์เลี้ยง - อายุ, น้ำหนัก, ชื่อ, เจ้าของ, ที่อยู่, สปีชี่ ฯลฯ

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

บริการ 2 - PetAccessor: บริการนี้รวบรวมสัตว์เลี้ยงและทำการตรวจสอบความถูกต้อง

บริการ 3,4 - การบริการระดับกลางเพิ่มเติม

บริการ 5 - ผู้ใช้ Inteface

สิ่งเหล่านี้โดยพลการมาก แต่ประเด็นก็ง่าย UI หรือบริการที่ผู้ใช้บางคนต้องการนำเสนอในทางใดทางหนึ่งวัตถุ "PET" นี้ มันจะต้องเรียกใช้บริการ API ซึ่งเรียกบริการซึ่งเรียกบริการ ฯลฯ จนกว่าจะถึงบริการที่รวบรวมข้อมูลที่จำเป็นและเริ่มต้นการถ่ายทอดกลับ ในที่สุดบริการ UI มีวัตถุ PET ที่จะแสดง

นี่เป็นเรื่องธรรมดา - แต่ด้วยความคิดที่แท้จริงของเราเราจึงจำลองวัตถุ PET ในทุกบริการ หลักการ (ไม่ต้องทำซ้ำตัวเอง) ใช้กับรหัสภายในบริการเท่านั้นและไม่ได้ใช้กับบริการต่าง ๆ แต่ประเด็นยังคงอยู่ที่นั่น ถ้าเราเพิ่มเขตข้อมูล ... เราต้องแก้ไข 5 บริการของ POJO ในแต่ละบริการ

- หรือ - เราสามารถให้ Pet-Objects-Library ซึ่งมีบางส่วนของ pojo จาก API และแต่ละบริการสามารถนำเข้า / อ้างอิงในไลบรารี ไม่มีการพึ่งพาตัวเอง แต่เป็นเพียงห้องสมุดทั่วไป ฉันชอบแนวคิดนี้เพื่อให้แต่ละบริการมีประเภทของวัตถุและการปรับปรุงที่ง่ายขึ้น แต่ฉันกังวลเกี่ยวกับพระเจ้าวัตถุ

อะไรคืออาชีพ / คอน - การออกแบบที่ดีที่สุดคืออะไร? คุณทำอะไรเพื่อส่งผ่านข้อมูลระหว่างบริการเพื่อลดการทำซ้ำ POJO คลาสเดียวกันในขณะที่ยังคงอยู่คู่กันอยู่


พระเจ้าวัตถุ? en.wikipedia.org/wiki/God_object

@DaiKaixian: แน่นอนคุณไม่แนะนำให้ OP ไปกับวัตถุพระเจ้าใช่มั้ย ซึ่งถือว่าเป็นรูปแบบการต่อต้านเป็นประจำ
Makoto

ฉันเห็นด้วยกับคำตอบของ @javaguy

และฉันอยากบอกว่าคุณสามารถพิจารณารูปแบบของผู้เยี่ยมชมได้ en.wikipedia.org/wiki/Visitor_pattern สร้างฟิลด์ทั้งหมดและ setter / getter ใน POJO และแชร์ระหว่าง microservices หากคุณต้องการดำเนินการบางอย่างกับ POJO ใน microservice อื่นให้เขียน VisitorClass บางส่วน

ขอบคุณ ความลังเลในการมี 'ห้องสมุดร่วม' นี้คือมันจะเติบโต และจะมีวัตถุอยู่ในนั้นที่ให้บริการ 1 & 3 เพียงแคร์หรือ 2 & 4 หรือทั้งหมดหรือรวมกันที่นั่น ชนิดของแพ็กเกจไลบรารี DTO ทั่วไปที่มี DTO ทั้งหมดไม่ว่าฉันจะใช้รูปแบบ vistor หรือ DTO POJO แบบง่าย ๆ หรืออะไรก็ตาม สิ่งนี้ยอมรับได้หรือไม่ที่จะรวมวัตถุเหล่านี้ทั้งหมด แต่พยายามที่จะรักษาไว้ให้ดีที่สุดเท่าที่จะทำได้หรือไม่? อย่างน้อยที่สุดก็มีการจัดเตรียมวัตถุสำหรับผู้ที่ต้องการหากพวกเขาต้องการใช้ ...

คำตอบ:


5

การออกแบบที่ดีที่สุดคืออะไร?

คุณสามารถนำวัตถุPet DTOเดียวกันมาใช้ซ้ำในบริการแบ็คเอนด์ (ซึ่งดำเนินการตามตรรกะทางธุรกิจทั่วไป) แต่เมื่อมาถึงระดับการนำเสนอ (ส่วนต่อประสานผู้ใช้) เป็นวิธีปฏิบัติที่ดีในการใช้FormBean (ถั่วอื่นที่มีฟิลด์เพิ่ม สำหรับการนำเสนอตรรกะ) เพื่อที่จะมีการแยกชัดเจนระหว่างการนำเสนอและตรรกะตรรกะทางธุรกิจ

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

คุณทำอะไรเพื่อส่งผ่านข้อมูลระหว่างบริการเพื่อลดการทำซ้ำ POJO คลาสเดียวกันในขณะที่ยังคงอยู่คู่กันอยู่

หากคุณใช้ถั่วเดี่ยวระหว่างธุรกิจและเว็บเทียร์คุณจะต้องเชื่อมโยงตรรกะการนำเสนอกับตรรกะทางธุรกิจที่ไม่เหมาะสมและคุณจะต้องเปลี่ยนบริการสำหรับข้อกำหนดใน Frontend (เช่นตัวอย่างรูปแบบวันที่ที่แตกต่างกัน) เพื่อแสดงในส่วนต่อประสานผู้ใช้) นอกจากนี้จะทำให้กระบวนการของประชากร / การคัดลอกข้อมูลข้ามถั่ว (เช่น DTO เพื่อ FormBean หรือ viceversa), คุณสามารถใช้ห้องสมุดเช่นนี้Apache BeanUtils.copyProperties()หรือรถดันดิน เพื่อหลีกเลี่ยงรหัสสำเร็จรูป


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

ใช่คุณสามารถนำวัตถุ DTO เดียวกันมาใช้ซ้ำในบริการแบ็คเอนด์ชนิดเดียวกันทั้งหมดอย่างเช่นของคุณPetServicesเพื่อหลีกเลี่ยงการทำซ้ำ แต่จุดของฉันไม่ได้เป็นแบ็กเอนด์และแบ็กเอนด์อย่างแน่นหนานั่นแหละ
นักพัฒนา

4

หาก DTO แสดงถึงเอนทิตีธุรกิจเดียวกันใน microservices ทั้งหมดควรมีคลาสเดียวที่แบ่งใช้ระหว่างเซอร์วิส มันเกือบจะไม่ถูกต้องที่จะมีรหัสที่ซ้ำกันสำหรับวัตถุเดียวกัน


3
การแบ่งปัน DTO ใน microservices นั้นเป็นฝันร้าย "รุ่นนี้มีฟิลด์นี้อยู่แล้วใช่มั้ยหืม?" คุณจะจบลงด้วยความยุ่งเหยิงที่แท้จริงหลังจากนั้นไม่นาน รหัสซ้ำเป็นสิ่งที่ดีในกรณีนี้
Mejmo

1

วิธีที่ฉันวางแผนที่จะทำในตอนนี้คือแต่ละแพ็กเกจบริการ DTO เท่านั้นและใส่ลงใน Nexus เป็น jar lib เมื่อบริการอื่น ๆ ต้องการบริการดังกล่าวก็จะได้รับ DTO lib (s) เป็นการพึ่งพาใน manve / gradle หากมีการเปิดตัว DTO เวอร์ชั่นใหม่ในบริการเดียวก็สามารถใช้งานได้ดีตราบเท่าที่เวอร์ชั่นเก่าในเวลาเดียวกันดังนั้นอย่าทำลายความเข้ากันได้แบบย้อนหลังเวอร์ชันและอื่น ๆ ดังนั้นนี่คือส่วนแบ็กเอนด์ถึงแบ็กเอนด์ นอกจากนี้เพื่อป้องกันการพึ่งพาวงจรคุณควรแยกบริการออกจากบรรจุภัณฑ์ dto

ตอนนี้ดู backend-to-frontend และในทางกลับกัน ฉันไม่เห็นด้วยกับความคิดเห็นก่อนหน้านี้ว่า UI เนื่องจากเลเยอร์การนำเสนอนั้นแตกต่างกัน มันไม่ใช่!!! UI เป็นอีกบริการหนึ่งสำหรับฉันซึ่งยังใช้และสร้างกิจกรรม

ทิศทางแบ็กเอนด์ไปยังส่วนหน้า สิ่งที่ฉันทำคือการแปลง POJO (dtos) เป็นอินเทอร์เฟซแบบเรียงพิมพ์และแพคเกจเป็น NPM และโหลดลงใน Nexus เช่นกัน โครงการที่ใช้ UI nodejs จะสิ้นเปลืองและใช้สิ่งเหล่านั้น นี่คือการให้บริการแก่ UI

Frontend-to-backend ทิศทาง สำหรับ UI เป็นบริการเลเยอร์เหตุการณ์ฉันแปลงอินเทอร์เฟซแบบ typescript และแปลงเป็น POJOs (dtos), แพคเกจเป็นขวดและอัปโหลดไปยัง Nexus (หรือ repo บางส่วน) ในรูปแบบของ jar ที่จะใช้บริการแบ็กเอนด์

กระบวนการเหล่านี้จัดการได้อย่างง่ายดายโดยกระบวนการ CI (Travis, Gitlab CI, ฯลฯ )

ความคิดเห็นใด ๆ เกี่ยวกับวิธีการนี้ยินดี

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