REST API เหมาะสำหรับโดเมนที่ใช้คำสั่ง / การดำเนินการอย่างไร


24

ในบทความนี้ผู้เขียนอ้างว่า

บางครั้งจำเป็นต้องเปิดเผยการดำเนินการใน API ที่โดยทั่วไปจะไม่สงบ

และนั่น

หาก API มีการดำเนินการมากเกินไปนั่นเป็นข้อบ่งชี้ว่ามันได้รับการออกแบบด้วยมุมมอง RPC แทนที่จะใช้หลักการ RESTful หรือ API ที่เป็นปัญหานั้นเหมาะสมสำหรับรุ่นประเภท RPC โดยธรรมชาติ

สิ่งนี้สะท้อนถึงสิ่งที่ฉันได้อ่านและได้ยินที่อื่นเช่นกัน

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

ตัวอย่างฉัน: การปิด VM ผ่านอินเตอร์เฟส REST

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

1. แก้ไขคุณสมบัติสถานะของทรัพยากร

PATCH /api/virtualmachines/42
Content-Type:application/json  

{ "state": "shutting down" }

(หรืออีกวิธีหนึ่งPUTบนทรัพยากรย่อย/api/virtualmachines/42/state)

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

2. ใส่หรือโพสต์บนคุณสมบัติการกระทำของทรัพยากร

PUT /api/virtualmachines/42/actions
Content-Type:application/json  

{ "type": "shutdown" }

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

ทั้งสองออกแบบสงบ

การออกแบบไหนดีกว่ากัน?

ตัวอย่างที่สอง: CQRS

ถ้าเรามีโดเมน CQRS ที่มีคำสั่ง "action" (aka) จำนวนมากที่อาจนำไปสู่การอัปเดตของการรวมหลาย ๆ ครั้งหรือไม่สามารถแมปกับการดำเนินการ CRUD ในทรัพยากรที่เป็นรูปธรรมและทรัพยากรย่อยได้

เราควรลองทำแบบจำลองคำสั่งให้มากที่สุดเท่าที่จะสร้างหรืออัพเดททรัพยากรที่เป็นรูปธรรมได้ที่ไหนบ้างที่เป็นไปได้ (ทำตามแนวทางแรกจากตัวอย่างที่ 1) และใช้ "จุดสิ้นสุดการกระทำ" สำหรับส่วนที่เหลือ?

หรือเราควรแมปคำสั่งทั้งหมดกับจุดสิ้นสุดการกระทำ (เช่นเดียวกับในวิธีที่สองของตัวอย่างที่ I)?

เราควรวาดเส้นตรงไหนดี? การออกแบบเริ่มสงบลงเมื่อใด

รุ่น CQRS เหมาะสมกับ RPC อย่าง API หรือไม่

ตามข้อความที่ยกมาข้างต้นมันเป็นอย่างที่ฉันเข้าใจ

อย่างที่คุณเห็นจากคำถามมากมายของฉันฉันสับสนเล็กน้อยเกี่ยวกับหัวข้อนี้ คุณช่วยฉันทำความเข้าใจให้ดีขึ้นได้ไหม?


"การสร้างการกระทำ" ดูเหมือนจะไม่สงบยกเว้นว่าการกระทำที่ดำเนินการมีตัวระบุทรัพยากรของตัวเองในภายหลัง มิฉะนั้นการเปลี่ยนคุณสมบัติ "สถานะ" ผ่าน PATCH หรือ PUT จะสมเหตุสมผลกว่า สำหรับส่วนของ CQRS ฉันยังไม่มีคำตอบที่ดี
เฟเบียน Schmengler

3
@Laiv ไม่มีอะไรผิดปกติกับที่ มันเป็นคำถามที่เกี่ยวกับวิชาเคมีฉันต้องการทำความเข้าใจกับเรื่องนี้ให้ลึกซึ้งยิ่งขึ้น
leifbattermann

คำตอบ:


19

ในกรณีแรก (ปิดระบบของ VMs) ฉันจะไม่พิจารณาทางเลือก OP RESTful จริงอยู่ถ้าคุณใช้แบบจำลองวุฒิภาวะของริชาร์ดสันเป็นปทัฏฐานพวกเขาทั้งคู่มีAPI 2 อันเพราะพวกเขาใช้ทรัพยากรและคำกริยา

อย่างไรก็ตามทั้งสองใช้การควบคุมสื่อหลายมิติและในความคิดของฉันมันเป็นประเภทเดียวของ REST ที่แตกต่างการออกแบบ RESTful API จาก RPC กล่าวอีกนัยหนึ่งติดกับระดับ 1 และ 2 และคุณจะมี API แบบ RPC ในกรณีส่วนใหญ่

เพื่อจำลองสองวิธีที่แตกต่างกันในการปิด VM ฉันจะต้องเปิดเผยตัว VM เป็นทรัพยากรที่ (มีสิ่งอื่น ๆ ) มีลิงก์:

{
    "links": [{
        "rel": "shut-down",
        "href": "/vms/1234/fdaIX"
    }, {
        "rel": "power-off",
        "href": "/vms/1234/CHTY91"
    }],
    "name": "Ploeh",
    "started": "2016-08-21T12:34:23Z"
}

หากลูกค้าต้องการปิดPloehVM มันควรจะไปตามลิงค์ที่มีshut-downประเภทความสัมพันธ์ (โดยปกติตามที่ระบุไว้ในRESTful Web Services Cookbookคุณจะต้องใช้ IRI หรือรูปแบบการระบุที่ซับซ้อนยิ่งขึ้นสำหรับประเภทความสัมพันธ์ แต่ฉันเลือกที่จะให้ตัวอย่างง่ายที่สุดเท่าที่จะทำได้)

ในกรณีนี้มีข้อมูลอื่น ๆ อีกเล็กน้อยที่จะมอบให้กับการกระทำดังนั้นลูกค้าควรสร้าง POST ที่ว่างเปล่าจาก URL ในhref:

POST /vms/1234/fdaIX HTTP/1.1

(เนื่องจากคำขอนี้ไม่มีเนื้อหามันจะดึงดูดการสร้างแบบจำลองนี้เป็นคำขอ GET แต่คำขอ GET ไม่ควรมีผลข้างเคียงที่สังเกตได้ดังนั้น POST จึงถูกต้องมากขึ้น)

ในทำนองเดียวกันหากลูกค้าต้องการปิด VM มันจะไปตามpower-offลิงก์แทน

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

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

โดยปกติฉันจะเข้ารหัสการกระทำใน URL ของตัวเองเพื่อให้ URL เป็น/vms/1234/shut-downและ/vms/1234/power-offแต่เมื่อการสอนนั้นจะแยกความแตกต่างระหว่างประเภทความสัมพันธ์ (ความหมาย) และ URL (รายละเอียดการใช้งาน)

คุณอาจพิจารณาทำ URL ที่สงบเงียบซึ่งไม่สามารถแฮกได้ทั้งนี้ขึ้นอยู่กับลูกค้าที่คุณมี

CQRS

เมื่อมาถึง CQRS หนึ่งในไม่กี่สิ่งที่เกร็กหนุ่ม Udi Dahan ตกลงเกี่ยวกับการเป็นที่CQRS ไม่ได้เป็นสถาปัตยกรรมระดับบนสุด ดังนั้นฉันจึงต้องระมัดระวังในการสร้าง RESTful API ด้วยเช่นเดียวกับ CQRS เพราะนั่นหมายความว่าลูกค้ากลายเป็นส่วนหนึ่งของสถาปัตยกรรมของคุณ

บ่อยครั้งที่แรงผลักดันที่อยู่เบื้องหลัง RESTful API ระดับที่ 3 คือคุณต้องการที่จะพัฒนา API ของคุณโดยไม่ทำให้ลูกค้าแตกและไม่สามารถควบคุมลูกค้าได้ หากนั่นคือแรงบันดาลใจของคุณ CQRS จะไม่ใช่ตัวเลือกแรกของฉัน


คุณหมายความว่าตัวอย่างแรกนั้นทั้งคู่ไม่ได้สงบเพราะพวกเขาไม่ได้ใช้การควบคุมสื่อหลายมิติ? แต่ฉันไม่ได้โพสต์คำตอบใด ๆ เฉพาะ URL คำขอและเนื้อหา
leifbattermann

4
@leifbattermann พวกเขาไม่สงบเพราะใช้เนื้อหาข้อความในการสื่อสารเจตนา เห็นได้ชัดว่า RPC หากคุณใช้ลิงก์เพื่อไปยังแหล่งข้อมูลเหล่านั้นแล้วทำไมคุณต้องสื่อสารความตั้งใจผ่านทางร่างกาย?
Mark Seemann

นั่นทำให้รู้สึก ทำไมคุณถึงแนะนำ POST แอ็คชั่น idempotent ไม่ใช่เหรอ? ไม่ว่าในกรณีใดคุณจะบอกลูกค้าของคุณว่าวิธีการใช้ HTTP แบบใด
leifbattermann

2
@ guillaume31 DELETEดูเหมือนจะแปลกสำหรับฉันเพราะหลังจากปิด vm จะยังคงอยู่เฉพาะในสถานะ "ปิดไฟ" (หรือ sth. เช่นนั้น)
leifbattermann

1
ทรัพยากรไม่จำเป็นต้องสะท้อนให้เห็นถึง VM atemporally มันสามารถแสดงอินสแตนซ์การดำเนินการของมัน
guillaume31

6

การปิด VM ผ่านอินเตอร์เฟส REST

นี้เป็นจริงตัวอย่างที่มีชื่อเสียงค่อนข้างออกมาโดยทิมเบรย์ในปี 2009

Roy Fielding พูดคุยถึงปัญหาแชร์การสังเกตนี้ :

ฉันชอบระบบที่ใช้งานสถานะที่ถูกตรวจสอบ (เช่นสถานะพลังงาน) เป็นการส่วนตัวที่ไม่สามารถแก้ไขได้

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

เซทแลดด์มีข้อมูลเชิงลึกที่สำคัญในปัญหา

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

นำสิ่งนี้กลับไปที่เครื่องรีบูต ฉันจะยืนยันว่าคุณจะโพสต์ไปที่ / vdc / 434 / cluster / 4894 / server / 4343 / reboots เมื่อคุณโพสต์แล้วคุณมี URI ซึ่งแสดงถึงการรีบูตเครื่องนี้และคุณสามารถรับการอัปเดตสถานะได้ ด้วยเวทมนต์ของการเชื่อมโยงหลายมิติการเป็นตัวแทนของ Reboot จะถูกเชื่อมโยงกับเซิร์ฟเวอร์ที่ถูกรีบูต

ฉันคิดว่าการทำ URI space นั้นถูกและ URI ก็ถูกกว่าด้วยซ้ำ สร้างชุดกิจกรรมจำลองเป็นคำนามและ POST, PUT และ DELETE ทันที!

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

ในภาษาที่ค่อนข้างจะน่าสนใจสิ่งที่คุณกำลังทำคือการกำหนดโปรโตคอลแอปพลิเคชันโดเมนสำหรับ "ปิด VM" และระบุทรัพยากรที่คุณต้องเปิดเผย / ใช้โปรโตคอลนั้น

ดูตัวอย่างของคุณเอง

PATCH /api/virtualmachines/42
Content-Type:application/json  

{ "state": "shutting down" }

ไม่เป็นไร; คุณไม่ได้ดำเนินการตามคำขอจริงๆเป็นแหล่งข้อมูลแยกต่างหาก แต่คุณยังคงสามารถจัดการได้

คุณพลาดการแสดงถึงความเปลี่ยนแปลงเล็กน้อย

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

ตัวอย่างเช่นคำสั่งการจัดรูปแบบชนิดสื่อบันทึกJSON Patchราวกับว่าคุณกำลังแก้ไขเอกสาร JSON โดยตรง

[
    { "op": "replace", "path": "state", "value": "shutting down" }
]

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

POST /api/virtualmachines/42/actions

สอดคล้องกับนิยายที่เรากำลังต่อท้ายการกระทำกับคิว

PUT /api/virtualmachines/42/latestAction

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

โปรดทราบว่าในขณะที่เรากำลังคุยกันเรื่องการสะกดคำของ URI - REST ไม่สนใจ /cc719e3a-c772-48ee-b0e6-09b4e7abbf8bเป็น URI ที่ไม่ย่อท้ออย่างสมบูรณ์แบบเท่าที่ REST เกี่ยวข้อง ความสามารถในการอ่านเช่นเดียวกับชื่อตัวแปรเป็นข้อกังวลแยกต่างหาก การใช้การสะกดที่สอดคล้องกับRFC 3986จะทำให้ผู้คนมีความสุขมากขึ้น

CQRS

ถ้าเรามีโดเมน CQRS ที่มีคำสั่ง "action" (aka) จำนวนมากที่อาจนำไปสู่การอัปเดตของการรวมหลาย ๆ ครั้งหรือไม่สามารถแมปกับการดำเนินการ CRUD ในทรัพยากรที่เป็นรูปธรรมและทรัพยากรย่อยได้

Greg Young บน CQRS

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

เมื่อคนส่วนใหญ่พูดคุยเกี่ยวกับ CQRS พวกเขากำลังพูดถึงการใช้รูปแบบ CQRS กับวัตถุที่แสดงถึงขอบเขตการบริการของแอปพลิเคชัน

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

อันนี้น่าประหลาดใจกว่าตัวอย่างก่อนหน้านี้ของคุณ เหตุผลนี้เป็นเรื่องง่าย: คำสั่งที่มีข้อความ

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

เราควรลองทำแบบจำลองคำสั่งให้มากที่สุดเท่าที่จะสร้างหรืออัพเดททรัพยากรที่เป็นรูปธรรมได้ที่ไหนบ้างที่เป็นไปได้ (ทำตามแนวทางแรกจากตัวอย่างที่ 1) และใช้ "จุดสิ้นสุดการกระทำ" สำหรับส่วนที่เหลือ?

ใช่ตราบเท่าที่ "ทรัพยากรที่เป็นรูปธรรม" เป็นข้อความแทนที่จะเป็นเอนทิตีในรูปแบบโดเมน

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

รุ่น CQRS เหมาะสมกับ RPC อย่าง API หรือไม่

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

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

การปฏิบัติต่อข้อความเป็นทรัพยากรที่เป็นเอกลักษณ์ของตัวเองนั้นมีข้อดีที่คุณสามารถใช้ PUT ได้การแจ้งเตือนส่วนประกอบของสื่อกลางถึงข้อเท็จจริงที่ว่าการจัดการข้อความนั้นเป็น idempotent เพื่อให้พวกเขาสามารถมีส่วนร่วมในการจัดการข้อผิดพลาดในบางกรณี . (หมายเหตุ: จากมุมมองของลูกค้าหากทรัพยากรมี URI ที่แตกต่างกันแล้วพวกเขาเป็นทรัพยากรที่แตกต่างกันความจริงที่ว่าพวกเขาทั้งหมดอาจมีรหัสตัวจัดการคำขอเดียวกันบนเซิร์ฟเวอร์ต้นทางคือรายละเอียดการใช้งานที่ซ่อนอยู่โดยเครื่องแบบ อินเตอร์เฟซ).

ฟีลดิง (2008)

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


2

คุณสามารถใช้ประโยชน์จากประเภทสื่อ 5 ระดับเพื่อระบุคำสั่งในฟิลด์ส่วนหัวของประเภทเนื้อหาของคำขอ

ในตัวอย่าง VM มันจะเป็นบางสิ่งบางอย่างตามบรรทัดเหล่านี้

PUT /api/virtualmachines/42
Content-Type:application/json;domain-model=PowerOnVm

> HTTP/1.1 201 Created
Location: /api/virtualmachines/42/instance

แล้วก็

DELETE /api/virtualmachines/42/instance
Content-Type:application/json;domain-model=ShutDownVm

หรือ

DELETE /api/virtualmachines/42/instance
Content-Type:application/json;domain-model=PowerOffVm

ดูhttps://www.infoq.com/articles/rest-api-on-cqrs


จะได้รับคำแนะนำ 5LMT เป็นโซลูชั่นที่นำเสนอและไม่ได้รับการสนับสนุนจากมาตรฐาน ฉันเจอบทความCQRSมาก่อนและเรียนรู้มากมายจากมัน
Peter L

1

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

มีสองวิธีในการควบคุมสถานะพลังงานของคอมพิวเตอร์บนโต๊ะของฉัน:

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

สำหรับ VM ทั้งสองสิ่งนี้สามารถสร้างแบบจำลองเป็นค่าบูลีนแบบอ่าน / เขียน:

  • power- เมื่อเปลี่ยนเป็นจะtrueไม่มีอะไรเกิดขึ้นนอกจากโน้ตที่วางไว้ว่าสวิตช์ถูกวางในสถานะนี้ เมื่อเปลี่ยนfalseเป็น VM จะได้รับคำสั่งให้เข้าสู่สถานะปิดเครื่องทันที เพื่อความสมบูรณ์ถ้าค่าไม่เปลี่ยนแปลงหลังจากการเขียนจะไม่มีอะไรเกิดขึ้น

  • onoff- เมื่อเปลี่ยนเป็นtrueไม่มีอะไรเกิดขึ้นถ้าpowerไม่falseเช่นนั้น VM จะได้รับคำสั่งให้เริ่มทำงาน เมื่อเปลี่ยนเป็นfalseไม่มีอะไรเกิดขึ้นถ้าpowerไม่falseเช่นนั้น VM จะได้รับคำสั่งให้แจ้งให้ซอฟต์แวร์ทำการปิดระบบอย่างเป็นระเบียบซึ่งจะทำแล้วแจ้งให้ VM ทราบว่าสามารถเข้าสู่สถานะปิดเครื่องได้ อีกครั้งเพื่อความสมบูรณ์ไม่มีการเปลี่ยนแปลงการเขียนไม่ทำอะไรเลย

ทั้งหมดนี้ทำให้เกิดความตระหนักว่ามีสถานการณ์หนึ่งเมื่อสถานะของเครื่องไม่ได้สะท้อนถึงสถานะของสวิตช์และนั่นคือในช่วงปิดเครื่อง powerจะยังคงอยู่trueและonoffจะเป็นfalseแต่ตัวประมวลผลยังคงปิดการทำงานและเพื่อที่เราจะต้องเพิ่มทรัพยากรอื่นเพื่อให้เราสามารถบอกได้ว่าเครื่องกำลังทำอะไรอยู่:

  • running- ค่าอ่านอย่างเดียวนั่นคือtrueเมื่อ VM กำลังทำงานและfalseเมื่อไม่ได้กำหนดโดยขอ hypervisor สำหรับสถานะของ

ผลที่สุดของเรื่องนี้คือถ้าคุณต้องการให้ VM เริ่มต้นคุณต้องตรวจสอบให้แน่ใจว่าได้ตั้งค่าpowerและonoffทรัพยากรtrueแล้ว (คุณสามารถอนุญาตให้powerข้ามขั้นตอนนี้ได้โดยทำให้การรีเซ็ตตัวเองดังนั้นหากตั้งค่าเป็นfalseมันจะกลายเป็นtrueหลังจากที่ VM หยุดทำงานด้วยการตรวจสอบด้วยตนเองอย่างหนักไม่ว่าจะเป็นสิ่งที่บริสุทธิ์อย่างสงบเงียบ หากคุณต้องการจะทำปิดระเบียบคุณตั้งonoffไปfalseและกลับมาใหม่เพื่อดูว่าเครื่องหยุดจริง, การตั้งค่าpowerไปfalseถ้ามันไม่ได้

เช่นเดียวกับโลกแห่งความจริงคุณยังคงมีปัญหาในการถูกสั่งให้เริ่มต้น VM หลังจากที่มันถูกonoffเปลี่ยนเป็นfalseแต่ยังคงเป็นrunningเพราะมันอยู่ในระหว่างการปิดระบบ วิธีที่คุณจัดการกับสิ่งนั้นคือการตัดสินใจเชิงนโยบาย


0

ทั้งสองออกแบบสงบ

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

มันน้อยกว่า

เฮ้เซิร์ฟเวอร์ไคลเอนต์ที่นี่คุณจะรังเกียจที่จะปิด VM

และอีกมากมายของ

เฮ้เซิร์ฟเวอร์ไคลเอนต์ที่นี่ฉันอัพเดทสถานะของทรัพยากร VM 42 เป็นสถานะปิดปรับปรุงสำเนาของทรัพยากรนี้แล้วทำในสิ่งที่คุณคิดว่าเหมาะสม

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

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

พลังของสิ่งนี้คือมันแยกไคลเอนต์ออกจากเซิร์ฟเวอร์ในแง่ของการควบคุมการไหล หากภายหลังเซิร์ฟเวอร์เปลี่ยนวิธีการทำงานกับ VMs ไคลเอ็นต์จะไม่สนใจ ไม่มีจุดปลายคำสั่งที่จะอัปเดต ใน RPC หากคุณเปลี่ยนจุดสิ้นสุด API จากshutdownเป็นshut-downคุณได้ทำให้ลูกค้าของคุณทั้งหมดเสียเนื่องจากพวกเขาไม่ทราบคำสั่งให้เรียกใช้บนเซิร์ฟเวอร์

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


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

ไม่มีปัญหากับการใช้ทรัพยากรวิธีการ HTTP และอื่น ๆ HTTP เป็นโปรโตคอลที่เงียบสงบหลังจากทั้งหมด เมื่อมีปัญหาเกิดขึ้นคุณกำลังใช้คำว่า "action endpoints" ใน REST มีทรัพยากรซึ่งแสดงถึงแนวคิดหรือสิ่งต่าง ๆ (เช่นเครื่องเสมือน 42 หรือบัญชีธนาคารของฉัน) และคำกริยา HTTP ใช้เพื่อถ่ายโอนสถานะของทรัพยากรเหล่านี้ระหว่างไคลเอนต์และเซิร์ฟเวอร์ นั่นแหละ. สิ่งที่คุณไม่ควรทำคือลองและสร้างคำสั่งใหม่โดยการรวมจุดปลายที่ไม่ใช่แหล่งข้อมูลเข้ากับกริยา HTTP ดังนั้น 'virtualmachines / 42 / actions' จึงไม่ใช่ทรัพยากรและไม่ควรมีอยู่ในระบบ RESTful
Cormac Mulhall

หรือเพื่อให้เป็นอีกวิธีหนึ่งที่ลูกค้าไม่ควรพยายามเรียกใช้คำสั่งบนเซิร์ฟเวอร์ (นอกเหนือจากคำกริยา HTTP ที่ จำกัด ที่เกี่ยวข้องกับการถ่ายโอนทรัพยากรของรัฐเท่านั้น) ไคลเอ็นต์ควรอัปเดตสำเนาของทรัพยากรแล้วเพียงแค่ขอให้เซิร์ฟเวอร์ยอมรับสถานะใหม่นี้ การยอมรับสถานะใหม่นี้อาจมีผลข้างเคียง (VM 42 ถูกปิดตัวลงทางกายภาพ) แต่นั่นเป็นสิ่งที่อยู่นอกเหนือความกังวลของลูกค้า หากไคลเอ็นต์ไม่พยายามเรียกใช้คำสั่งบนเซิร์ฟเวอร์จะไม่มีการเชื่อมต่อผ่านคำสั่งเหล่านั้นระหว่างไคลเอนต์และเซิร์ฟเวอร์
Cormac Mulhall

คุณสามารถเรียกใช้คำสั่งบนทรัพยากร ... คุณจะทำอย่างไรพูดว่า "เงินฝาก" และ "ถอน" ในบัญชีธนาคาร? มันจะใช้ CRUD กับสิ่งที่ไม่ใช่ CRUD
Konrad

ควรใช้POST /api/virtualmachines/42/shutdownแทนการใช้"ผลข้างเคียง" ใด ๆ API จะต้องเข้าใจกับผู้ใช้ฉันจะรู้ได้อย่างไรว่าตัวอย่างเช่นDELETE /api/virtualmachines/42จะปิด VM ลง ผลข้างเคียงสำหรับฉันคือข้อผิดพลาดเราควรออกแบบ API ของเราให้มีความเข้าใจและอธิบายตนเอง
Konrad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.