จะอธิบายการเปลี่ยนแปลงทางสถาปัตยกรรมที่ทำลายมาตรฐานของ REST ได้อย่างไร?


37

ฉันเสนอการเปลี่ยนแปลงโครงการซอฟต์แวร์ที่ได้รับการออกแบบมาไม่ดีนักซึ่งมีปัญหามากมาย ในระดับสูงโครงการใช้ Angular บน front-end และใช้ REST APIs ต่างๆ ซึ่งเป็นสิ่งที่ยอดเยี่ยม (ฉันไม่เห็นความจำเป็นในการเปลี่ยนแปลงเทคโนโลยีหรือเครื่องมือของเรา) ปัญหาคือรหัสฐานมีขนาดใหญ่กว่าใน API มากกว่าฝั่งเซิร์ฟเวอร์ ตรรกะทางธุรกิจส่วนใหญ่อาศัยอยู่ใน UI ด้วย REST APIs ที่เป็นอินเตอร์เฟสฐานข้อมูล CRUD อย่างง่ายไปยังเลเยอร์ UI

ตัวอย่างเช่น POST ให้กับลูกค้าจะสร้างระเบียนลูกค้าในขณะที่ PUT จะแก้ไขลูกค้ารายนั้น ไม่มากและไม่มากน้อย อย่างไรก็ตามตรรกะทางธุรกิจของเรานั้นมีความต้องการมากกว่านั้น กระบวนการทั่วไปในการสร้างลูกค้านั้นค่อนข้างมากกว่าการแทรก 1 บันทึกฐานข้อมูล มันจะจัดเตรียมข้อมูลในตารางที่จำเป็นอื่น ๆ ทำการตรวจสอบความถูกต้องและการคำนวณบางอย่าง ฯลฯ ฉันต้องการทำการเรียก POST / PUT หนึ่งครั้งเพื่อสรุปพฤติกรรมทั้งหมดนี้เพื่อลดภาระของลูกค้าที่บริโภค

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


44
การ จำกัด API ของคุณไปที่ CRUD ทำให้การ "RESTful" เป็นการแลกเปลี่ยนที่ไม่ดี
Robert Harvey

38
@EsbenSkovPedersen: เพื่อนที่ดีที่สุดตลอดกาล?
Robert Harvey

5
แทนที่จะกังวลเกี่ยวกับว่าสอดรับบริการของคุณเพื่อ REST (iirc แทบไม่มีทำ) ผมกังวลเพิ่มเติมเกี่ยวกับการสอดคล้องกับHTTP ข้อมูลจำเพาะ api ส่วนใหญ่ที่ฉันทำงานด้วยก็ไม่สอดคล้องกับสเป็ค แต่มันก็เป็นเป้าหมายที่คุ้มค่าและคุ้มค่ากว่า
aaaaaa

7
@aaaaaa เหตุผลที่แทบไม่มีบริการใดที่สอดคล้องกับ REST คือไม่มีใครสามารถตัดสินใจได้ว่า REST คืออะไร ข้อตกลงเดียวที่ฉันพบคือ "คนอื่นทำผิด"
Mark

16
- "จะอธิบายการเปลี่ยนแปลงทางสถาปัตยกรรมที่ทำลายมาตรฐานของ REST ได้อย่างไร" - ทำลายการตรวจสอบ ( ขออภัยสำหรับความคิดเห็นที่ไม่เป็นมืออาชีพมันแข็งแกร่งกว่าฉัน )
luk32

คำตอบ:


49

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

Service oriented architecture.

คุณกำลังเสนอให้ออกแบบระบบใหม่เพื่อให้กฎเกณฑ์ทางธุรกิจและข้อมูลของคุณอยู่ในที่เดียวกัน ได้อย่างมีประสิทธิภาพนั่นคือความหมายของการให้บริการ ; เห็นพูดคุย Udi Dahan บนขอบเขตการค้นหาบริการ

แถบด้านข้าง: ตามที่เอริคระบุไว้สิ่งนี้ไม่มีส่วนเกี่ยวข้องกับ "REST" ไม่มีเหตุผลใดที่คุณไม่สามารถใส่ REST API (ซึ่งก็คือ API ที่ตรงตามข้อ จำกัด ของรูปแบบสถาปัตยกรรม REST ) ต่อหน้าบริการของคุณ แต่นั่นอาจไม่ชัดเจนสำหรับผู้ที่เข้าใจ REST เพื่อหมายถึงการแมปการดำเนินการฐานข้อมูลกับวิธี HTTP

อาจเป็นการลงทุนที่คุ้มค่าในการเปลี่ยนความเข้าใจของผู้ชม REST


32
และอาจไม่คุ้มค่ากับการลงทุนใน REST เลย ถ้าคุณอ่านวิทยานิพนธ์ของ Roy Fielding (หรือวิธีที่ฉันอธิบาย REST กับภรรยาของฉัน ) จุดประสงค์ที่แท้จริงของ REST คือการให้การแสดงที่เป็นที่ยอมรับสำหรับทรัพยากรบนอินเทอร์เน็ตดังนั้นเครื่องที่แตกต่างกันทางอินเทอร์เน็ตจะมีวิธีมาตรฐานในการจัดการทรัพยากร . แอปพลิเคชันที่เป็นของเอกชนอาจไม่ต้องการความสามารถนี้
Robert Harvey

29

REST ไม่ใช่ CRUD "การโต้เถียง" นั้นมีพื้นฐานมาจากความเข้าใจที่คลาดเคลื่อนในแง่ที่ว่า REST คืออะไร ฉันไม่เห็นอะไรเลยในโพสต์ของคุณที่ระบุว่าการเปลี่ยนแปลงของคุณจะทำให้ API ของคุณสงบลงมากขึ้นหรือน้อยลง


6
ไม่เลยมันไม่ใช่แผนที่ที่สมบูรณ์แบบสำหรับ CRUD แต่มันเดินและพูดคุยและร้องเพลงมากเหมือนกับ CRUD อย่างน้อยก็ในแบบที่คนส่วนใหญ่ตีความมัน
Robert Harvey

11
@ RobertHarvey ฉันคิดว่ามันเป็นความเข้าใจ (ผิด) ที่เป็นปัญหาที่นี่
JimmyJames

4
@JimmyJames: มันเป็นความเข้าใจผิดที่แพร่หลาย มีแรงผลักดันที่จะทำให้สิ่งต่าง ๆ "สงบ" เมื่อคนส่วนใหญ่ไม่เข้าใจว่าประโยชน์คืออะไรหรือประโยชน์เหล่านั้นจะนำไปใช้กับพวกเขาอย่างไร
Robert Harvey

4
@ RobertHarvey ฉันคิดว่าคุณกำลังพูดว่าถ้าทำผิดวิธีคือ REST แล้ว REST ไม่ควรเป็นเป้าหมาย ตกลง แต่วิธีที่ฉันเห็นมันการเรียกสิ่งนี้ว่า 'ไม่ใช่ REST' นั้นเป็นเรื่องไร้สาระและฉันก็เป็นผู้สนับสนุนคนสำคัญในการเรียกพล่ามให้กับนักสู้ คำต่างๆจำเป็นต้องมีความหมายที่เข้าใจกันโดยทั่วไปว่ามีประโยชน์
JimmyJames

5
@RobertHarvey ได้รับสิทธิ์ แต่นั่นจะไม่เกิดขึ้นตราบใดที่ยังมีคนจำนวนมากที่เต็มใจแก้ไขข้อผิดพลาดเหล่านี้ในระยะยาว ฉันยังไม่พร้อมที่จะโยนผ้าเช็ดตัว
JimmyJames

24

สิ่งหนึ่งที่ต้องจำไว้คือต่อไปนี้ ... ไม่ตรวจสอบฝั่งเซิร์ฟเวอร์กฎธุรกิจของคุณหมายความว่าคุณเชื่อถือสิ่งใดก็ตามที่เข้ามาโดยปริยายผ่านการพูดคำขอ POST นั้นถูกต้อง

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

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


5
นี่คือคำตอบที่มีประโยชน์ที่สุดที่นี่: API คือพื้นผิวการโจมตีไม่ใช่อินพุตไปยังไคลเอ็นต์ คำขอ API ใด ๆ สามารถปลอมแปลงได้ ดังนั้นทุกสิ่งที่สามารถทำได้ด้วย API บริสุทธิ์คือสิ่งที่ตัวย่อสคริปต์ที่ไม่มีความสามารถและเป็นอันตรายสามารถทำได้ อาจใช้ซอฟต์แวร์ไคลเอ็นต์เพื่อมอบประสบการณ์การใช้งานที่ดีขึ้น แต่เป็นเซิร์ฟเวอร์ที่จำเป็นต้องมีการบังคับใช้กฎ
cmaster

10

หากต้องการเพิ่มคำตอบที่ดีอื่น ๆ ที่นี่:

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

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

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

จากคำถามของคุณคุณมีทรัพยากรที่เรียกว่าลูกค้า ทุกสิ่งที่จำเป็นในการสร้างทรัพยากรลูกค้าที่ถูกต้องสามารถและควรได้รับการจัดการในPOSTทรัพยากรฐานลูกค้า (หรือสลับ / เลือกเป็นทางเลือกใน PUT ไปยังทรัพยากรลูกค้าเฉพาะหากไม่มีอยู่) REST พูดอะไรเกี่ยวกับจำนวน บันทึกฐานข้อมูลที่คุณต้องสร้างในการโทรที่กำหนด ดังที่ Colin Young แสดงความคิดเห็นไม่จำเป็นต้องมีฐานข้อมูลเลยมันไม่เกี่ยวข้องทั้งหมดกับการใช้บริการจากมุมมอง REST


3
ส่วนที่เหลือไม่ได้พูดอะไรเกี่ยวกับบันทึกฐานข้อมูล ฉันสามารถสร้างบริการ REST ที่ควบคุมวาล์วน้ำและเปิดเผยวาล์วน้ำแหล่งน้ำและระดับถังน้ำ คุณสามารถโต้เถียงวัตถุทางกายภาพตัวเองเป็น "ฐานข้อมูล" แต่ที่ยืดสิ่งเล็กน้อย
โคลินยัง

@ColinYoung ใช่ขอบคุณที่ช่วยอธิบาย
JimmyJames

3

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

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

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

ลองดูที่วัตถุลูกค้าของคุณ

ปัญหา:

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

วิธีการแก้:

สร้าง API ปลายทางเพื่อสร้างลูกค้า คุณรู้ว่าคุณไม่ต้องการที่จะมีจุดสิ้นสุด "/ ลูกค้า / สร้าง" หรือแม้กระทั่ง "/ สร้างลูกค้า" เพราะสร้างเป็นคำกริยาและจะละเมิดส่วนที่เหลือ ดังนั้นคำนามมัน "/ การสร้างลูกค้า" สามารถใช้งานได้ ตอนนี้เมื่อคุณโพสต์วัตถุ CustomerCreation ของคุณมันจะส่งฟิลด์ที่จำเป็นทั้งหมดเพื่อให้ลูกค้าสร้างขึ้นอย่างสมบูรณ์ จุดสิ้นสุดจะทำให้มั่นใจได้ว่าข้อมูลนั้นสมบูรณ์และถูกต้อง (ส่งคืน 400 หรือบางสิ่งถ้าไม่ผ่านการตรวจสอบ) และอาจยังคงอยู่ทั้งหมดภายในธุรกรรม db เดียว

หากคุณต้องการปลายทางสำหรับวัตถุ GET / ลูกค้านั่นก็เป็นเรื่องดี คุณสามารถมีทั้ง เคล็ดลับคือการสร้างจุดสิ้นสุดที่ตอบสนองความต้องการของผู้บริโภค

ข้อดี:

  1. คุณรับประกันได้ว่าคุณจะไม่ได้รับสถานะที่ไม่ดี
  2. จริง ๆ แล้วมันง่ายกว่าสำหรับ UI ที่พัฒนาขึ้นหากพวกเขาไม่จำเป็นต้องสั่ง "รู้" ของคำขอ, ตรวจสอบข้อกังวล, ฯลฯ
  3. มันไม่ได้เป็นเรื่องช่างพูดของ API ช่วยลดเวลาแฝงของการร้องขอเครือข่าย
  4. ง่ายต่อการทดสอบและกำหนดแนวคิดสถานการณ์ (ชิ้นส่วนที่ขาดหายไป / ผิดรูปแบบจาก UI จะไม่กระจายไปตามคำขอซึ่งบางส่วนอาจล้มเหลว)
  5. จะช่วยให้การห่อหุ้มของตรรกะทางธุรกิจที่ดีขึ้น
  6. โดยทั่วไปจะทำให้การรักษาความปลอดภัยง่ายขึ้น (เนื่องจากผู้ใช้งานทางธุรกิจและตรรกะ orchestration ใน UI สามารถแก้ไขได้)
  7. มีแนวโน้มที่จะลดการทำซ้ำตรรกะ (มีแนวโน้มที่คุณจะมีลูกค้ามากกว่า 2+ คนของ API มากกว่า 2+ API ที่ให้การเข้าถึงข้อมูลเดียวกัน)
  8. ยังคงสงบ 100%

ข้อเสีย:

  1. อาจใช้งานได้มากกว่าสำหรับแบ็กเอนด์ส่วนหลัง (แต่อาจไม่ได้อยู่ในระยะยาว)

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

ประสบการณ์ของฉันเองคือเมื่อ devs ในทีมของฉันเริ่มใช้กลยุทธ์นี้พวกเขาเกือบจะเห็นประโยชน์ทันที

การศึกษาเพิ่มเติม:

บทความจาก thinkworks นี้ช่วยให้ฉันได้รับความคิดในการสร้างแบบจำลองการกระทำเป็นวัตถุโดยใช้ตัวอย่างที่ใช้ได้จริง: https : // www. Thoughtworks.com/insights/blog/rest-api-design-resource-modeling

ฉันขอแนะนำให้อ่านข้อมูลเกี่ยวกับCQRS และการจัดหากิจกรรมเนื่องจากเกี่ยวข้องกับสิ่งเหล่านี้อย่างแน่นอน (เช่นการหย่า API ของคุณจากตรรกะการคงอยู่จริง) ฉันไม่ทราบว่าเพื่อนร่วมงานของคุณเต็มใจที่จะอ่านสิ่งเหล่านี้อย่างไร แต่มันอาจช่วยให้คุณมีความชัดเจนมากขึ้นและช่วยให้คุณอธิบายได้


" เพราะสร้างเป็นคำกริยาและจะละเมิดส่วนที่เหลือ " - ถูกต้องอย่างแน่นอน กล่าวอีกนัยหนึ่งมันจะเป็นแนวทางที่ 47.258.346 ในการรัน " RPC over REST " ซึ่งเป็นสิ่งที่ฉันจะแอตทริบิวต์ "ผิดธรรมชาติ" อย่างน้อยเพราะมันใช้ในทางที่ผิดและวิธีการ RESTful ผิด (พวกเขามีกรณีการใช้งานของพวกเขา แต่ RPC ไม่ได้เป็นหนึ่งในพวกเขา) และยังมีประสิทธิภาพ
JensG
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.