วิธีแบ่งปัน DTO ในไมโครไซต์หรือไม่


33

สถานการณ์ของฉันเป็นดังนี้

ฉันกำลังออกแบบระบบที่ออกแบบมาเพื่อรับข้อมูลจากเซ็นเซอร์ประเภทต่างๆและแปลงแล้วยืนยันให้ใช้กับส่วนหน้าและบริการวิเคราะห์ต่างๆในภายหลัง

ฉันพยายามออกแบบทุกบริการให้มีความเป็นอิสระมากที่สุด แต่ฉันมีปัญหา ทีมได้ตัดสินใจใช้ DTO ที่เราต้องการใช้ บริการภายนอก (ผู้รับข้อมูลเซ็นเซอร์) จะรับข้อมูลด้วยวิธีที่ไม่ซ้ำกันจากนั้นแปลงเป็นวัตถุ JSON (DTO) และส่งออกไปยัง Message Broker ผู้บริโภคของข้อความจะรู้วิธีอ่านข้อความข้อมูลเซ็นเซอร์อย่างแม่นยำ

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

ฉันจะสร้างระบบผิดหรือเปล่า? ถ้าไม่เป็นเช่นนั้นวิธีใดบ้างหรืออย่างน้อยที่สุดเพื่อบรรเทาความกังวลของฉัน


คุณใช้ DTO ประเภทใดและโปรโตคอลใดที่คุณใช้ระหว่างบริการ ยกตัวอย่างเช่นการแชร์protoไฟล์สำหรับ gRPC หรือavroschema สำหรับ Kafka และสร้าง DTO ในบริการทั้งคู่ แต่ฉันจะไม่แชร์ไลบรารีที่ใช้ร่วมกันระหว่างสองโครงการ
Vincent Savard

สตริง JSON ที่เข้ารหัสและ AMQP ฉันไม่ต้องการใช้ภาษาใดเป็นพิเศษ
nbaughman

คำตอบ:


38

คำแนะนำของฉัน? อย่าแชร์ DTOs เหล่านี้ระหว่างแอปพลิเคชันในไลบรารีทุกประเภท หรืออย่างน้อยก็ไม่ต้องทำตอนนี้

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

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

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

แต่ถ้าสถานการณ์นี้รบกวนคุณจริงๆคุณสามารถทำตามกฎของสาม :

มี "กฎสามข้อ" สองข้อในการใช้ซ้ำ: (a) เป็นการยากที่จะสร้างส่วนประกอบที่ใช้ซ้ำได้สามครั้งเป็นส่วนประกอบแบบใช้ครั้งเดียวและ (b) ส่วนประกอบที่สามารถนำมาใช้ซ้ำได้ควรลองใช้ในสามแอปพลิเคชันที่แตกต่างกัน เพื่อยอมรับลงในไลบรารีที่ใช้ซ้ำ

ดังนั้นพยายามรออีกเล็กน้อยก่อนแบ่งปัน DTO นี้ระหว่างบริการ


1
ชื่นชมมาก นี่เป็นหนึ่งในข้อกังวลสำคัญที่ฉันได้ทำต่อไป ไม่เพียงพอที่จะทำให้ฉันตื่น แต่ก็พอที่จะทำให้ฉันกังวล
nbaughman

4
DTO ที่ซ้ำกัน (ในบริการที่แตกต่างและเป็นอิสระมาก) ไม่ละเมิด DRY แค่นั้นแหละ.
Laiv

3
สันนิษฐานว่าไม่มีเหตุผลที่จะไม่คัดลอกซอร์สโค้ด DTO โดยตรงจากโครงการหนึ่งไปยังอีกโครงการหนึ่งเป็นการดำเนินการแบบครั้งเดียวแม้ว่าจะมีการลบส่วนใด ๆ ที่ไม่จำเป็นในโครงการใหม่
bdsl

1
แม้แต่บริการทั้งหมดอาจถูกลบไม่ทำให้เกิดปัญหาใหญ่กับระบบทั้งหมด จะเป็นการดี
Laiv

4
เพื่อชี้แจงสาระสำคัญของคำตอบเมื่อพัฒนา microservices แต่ละบริการควรได้รับการพัฒนาราวกับว่าพวกเขาไม่ทราบเกี่ยวกับบริการอื่น ๆ ยกเว้นสัญญาจริงที่อาจต้องใช้
Jonathan van de Veen

12

เมื่อพูดถึง Microservices วงจรชีวิตของการพัฒนาบริการควรเป็นอิสระเช่นกัน * * * *

SLDC ที่แตกต่างกันและทีมพัฒนาที่แตกต่างกัน

ในระบบ MS จริงอาจมีหลายทีมที่เกี่ยวข้องกับการพัฒนาระบบนิเวศซึ่งแต่ละแห่งมีหน้าที่ให้บริการอย่างน้อยหนึ่งรายการ ในทางกลับกันทีมเหล่านี้อาจตั้งอยู่ในสำนักงานต่าง ๆ เมืองประเทศแผน ... บางทีพวกเขาอาจไม่รู้จักกันสิ่งที่ทำให้การแบ่งปันความรู้หรือรหัสยากมาก (ถ้าเป็นไปได้) แต่สิ่งนี้อาจจะสะดวกมากเพราะรหัสที่ใช้ร่วมกันแสดงถึงการใช้เหตุผลร่วมกันและสิ่งที่สำคัญที่ต้องจำก็คือสิ่งใดก็ตามที่เหมาะสมสำหรับทีมเฉพาะไม่จำเป็นต้องทำเพื่อทีมอื่น ตัวอย่างเช่นเมื่อได้รับลูกค้า DTO อาจแตกต่างกันไปขึ้นอยู่กับบริการที่กำลังเล่นอยู่เนื่องจากลูกค้าถูกตีความ (หรือมองเห็น) แตกต่างจากบริการแต่ละบริการ

ความต้องการที่แตกต่างเทคโนโลยีที่แตกต่าง

SLDC ที่แยกได้ยังช่วยให้ทีมสามารถเลือกสแต็กที่เหมาะสมกับความต้องการมากที่สุด การกำหนด DTOs ที่ใช้ในเทคโนโลยีเฉพาะจะเป็นการจำกัดความสามารถของทีมที่จะเลือก

DTO ไม่ใช่กฎเกณฑ์ทางธุรกิจและสัญญาบริการ

DTOs อะไรจริงๆ วัตถุธรรมดาที่ไม่มีเป้าหมายอื่นนอกจากย้ายข้อมูลจากด้านหนึ่งไปอีกด้านหนึ่ง กระเป๋าของ getters และ setters ไม่ใช่ "ความรู้" ที่คุ้มค่าที่นำมาใช้ใหม่โดยรวมเพราะไม่มีความรู้เลย ความผันผวนของพวกเขายังทำให้ผู้สมัครที่ไม่ดีสำหรับการแต่งงาน

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

ธุรกิจที่แตกต่างการตีความที่แตกต่าง

ในขณะที่อาจมี (และจะมี) แนวคิดการตัดต่อระหว่างบริการ แต่ก็ไม่ได้หมายความว่าเราต้องกำหนดแบบจำลองมาตรฐานเพื่อบังคับให้บริการทั้งหมดตีความในลักษณะเดียวกัน

กรณีศึกษา

บอกว่า บริษัท ของเรามีสามแผนกบริการลูกค้า , การขายและการจัดส่งสินค้า สมมติว่าแต่ละรายการเผยแพร่บริการหนึ่งรายการขึ้นไป

บริการลูกค้าเนื่องจากโดเมนภาษาบริการการดำเนินการรอบแนวคิดของลูกค้าที่ลูกค้าเป็นบุคคล ยกตัวอย่างเช่นลูกค้ามีการจำลองเป็นชื่อ , นามสกุล , อายุ , เพศ , อีเมล , โทรศัพท์ฯลฯ

ตอนนี้พูดว่าการขายและการส่งสินค้าเป็นตัวอย่างการบริการตามภาษาของโดเมนนั้น ๆ ในภาษาเหล่านี้ลูกค้าแนวคิดจะปรากฏขึ้นเช่นกัน แต่มีความแตกต่างเล็กน้อย กับพวกเขาลูกค้า ไม่ได้ (จำเป็น) บุคคล สำหรับ การขายลูกค้าเป็นจำนวนเอกสารบัตรเครดิตและอยู่เรียกเก็บเงินสำหรับการจัดส่งสินค้าชื่อเต็มและที่อยู่จัดส่งเกินไป

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

ลิงก์ที่เกี่ยวข้อง


* ที่นี่เป็นจุดแข็งของสถาปัตยกรรมนี้


ขอขอบคุณ! กรณีศึกษาเป็นสิ่งที่ช่วยให้ฉันตัดสินใจได้ว่าจะแบ่งปัน DTO หรือไม่ ตอนนี้ฉันแน่ใจว่าทำไมฉันไม่ต้องการแบ่งปัน
อิกอร์

8

ฉันพยายามออกแบบทุกบริการให้มีความเป็นอิสระมากที่สุด

คุณควรจะเผยแพร่เหตุการณ์ เหตุการณ์เป็นข้อความบางประเภทที่แสดงถึงข้อเท็จจริงที่ชัดเจนเกี่ยวกับสิ่งที่เกิดขึ้น ณ เวลาใดเวลาหนึ่ง

แต่ละบริการควรมีความรับผิดชอบที่กำหนดไว้อย่างดีและควรมีความรับผิดชอบในการเผยแพร่เหตุการณ์ที่เกี่ยวข้องกับความรับผิดชอบนั้น

นอกจากนี้คุณต้องการให้กิจกรรมของคุณเป็นตัวแทนกิจกรรมที่เกี่ยวข้องกับธุรกิจไม่ใช่กิจกรรมทางเทคนิค เช่นต้องการOrderCancelledเหตุการณ์กับผู้ที่มีOrderUpdatedstatus: "CANCELLED"

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

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

ในกรณีของคุณ แต่เป็นของคุณจะถูกเผยแพร่ข้อมูลเซ็นเซอร์ก็จะทำให้ความรู้สึกที่มีให้บริการฟังเหตุการณ์ที่เกิดขึ้นและเผยแพร่กระแสใหม่ของ "กิจกรรมทางธุรกิจ" เช่น,TemperatureThresholdExceededTemperatureStabilised

และระมัดระวังเกี่ยวกับการสร้าง microservices มากเกินไป Microservices อาจเป็นวิธีที่ยอดเยี่ยมในการห่อหุ้มความซับซ้อน แต่ถ้าคุณไม่พบขอบเขตบริการที่เหมาะสมความซับซ้อนของคุณจะอยู่ในการรวมบริการ และนั่นคือฝันร้ายที่ต้องรักษา

มันจะดีกว่าที่จะมีบริการน้อยเกินไปมีขนาดใหญ่เกินไปกว่ามีบริการเล็กเกินไป


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

2
@ Nickdb93 - ในกรณีของคุณในขณะที่คุณกำลังเผยแพร่ข้อมูลเซ็นเซอร์มันมีเหตุผลที่จะต้องมีบริการฟังเหตุการณ์และเผยแพร่กระแสใหม่ของ "กิจกรรมทางธุรกิจ" เช่นอุณหภูมิ ThresholdExceeded, อุณหภูมิคงที่ (เพิ่มเพื่อตอบ)
Pete
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.