ฉันควรใช้กริยา HTTP ใดเพื่อกระตุ้นการดำเนินการในบริการเว็บ REST


80

reloadฉันกำลังดำเนินการบริการเว็บสงบและเป็นหนึ่งในการกระทำที่มีอยู่จะเป็น มันจะใช้ในการโหลดการกำหนดค่าแคช ฯลฯ

เราเริ่มต้นด้วยGETURI แบบง่าย ๆดังนี้: ${path}/cache/reload(ไม่มีการส่งพารามิเตอร์ใด ๆ เท่านั้นที่เรียกว่า URI) ฉันทราบว่าไม่ควรแก้ไขข้อมูลด้วยคำขอ GET

กริยาที่ถูกต้องที่จะใช้เพื่อเรียกใช้การกระทำ / คำสั่งในบริการเว็บสงบคืออะไร?

การโหลดซ้ำเป็นคำสั่งของเว็บเซอร์วิส REST ที่โหลดแคช / การกำหนดค่า / etc ของตัวเองอีกครั้ง ไม่ใช่วิธีการส่งคืนข้อมูลไปยังไคลเอนต์

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

ฉันพบรายละเอียดนี้เป็น asnwer บน Stack Overflow abot หัวเรื่อง: https://stackoverflow.com/questions/16877968/


1
"การโหลดซ้ำ" เป็นความรู้สึกของแอปที่จะรีเฟรชข้อมูลที่จะแสดงหรือไม่ มีความแตกต่างระหว่างการโหลดซ้ำและเพิ่งได้รับข้อมูลอีกครั้งหรือไม่?
Sean Redmond

1
@SeanRedmond ไม่ข้อมูลจะไม่ถูกส่งไปยังลูกค้า ในความเป็นจริงลูกค้าพูดกับเว็บเซอร์วิส REST เพื่อเรียกใช้งานและคำสั่งภายใน (โหลดซ้ำ) สิ่งที่ชอบ: "มีการเปลี่ยนแปลงการกำหนดค่าจำนวนมากในฐานข้อมูลดังนั้นเว็บเซอร์วิส REST จึงโหลดลงในหน่วยความจำของคุณทันที"
Renato Dinhani

ซ้ำข้ามไซต์: stackoverflow.com/q/15340946/319403
cHao

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

คำตอบ:


25

ฉันไม่คิดว่าจะมีคำกริยาที่เหมาะสมสำหรับการกระทำนี้เพราะธุรกรรมนี้ไม่ใช่ "สงบ" "s" และ "t" หมายถึง "การถ่ายโอนสถานะ" และไม่มีการถ่ายโอนที่นี่ หรือกล่าวอีกนัยหนึ่งโดยนิยามที่เข้มงวดที่สุดคำกริยาอย่าง PUT และ POST มักใช้กับคำนามและ "reload" จะมีคำกริยาเสมอ

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


ฉันยอมรับว่าสิ่งนี้ไม่สงบ แต่อาจมีประโยชน์ ฉันคิดว่าคุณควรจะแนะนำ PUT แต่เพราะอาจเป็น idempotent แต่ไม่ใช่ nullimpotent
Aaron Greenwald

@Aaron การเปรียบเทียบ idempotent และ nullimpotent นั้นดีและดี แต่คุณจะทราบได้อย่างไรว่ามันไม่น่าประทับใจ?
Craig

@ Craig เป็น idempotent หากใช้หลาย ๆ ครั้งจะมีผลเหมือนกันกับการใช้งานเพียงครั้งเดียว มันเป็น nullipotent ถ้าเรียกใช้ครั้งเดียวหรือหลายครั้งมีผลเช่นเดียวกันกับเซิร์ฟเวอร์เช่นเดียวกับการเรียกใช้มันเป็นศูนย์ครั้ง en.wikipedia.org/wiki/Idempotence
Aaron Greenwald

5
@AaronGreenwald“ notimpotent” [not-im-poht-nt] [not-im-pawr-tnt] - คำคุณศัพท์ - 1. การเล่นคำ,“ ไม่สำคัญ” คำตรงข้ามของคำคุณศัพท์“ สำคัญ” 2. ขำขัน… ;-)
Craig

@Craig ฉันพลาดไปอย่างสิ้นเชิง :)
Aaron Greenwald

75

หากคุณต้องการพักสงบอย่าคิดคำกริยาเพื่อดำเนินการใด ๆ ให้คิดถึงสถานะที่คุณต้องการให้ทรัพยากรดำเนินการหลังจากที่ไคลเอ็นต์ทำบางสิ่ง

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

ดังนั้นลูกค้าจึงใส่สถานะใหม่ไปยังเซิร์ฟเวอร์สำหรับทรัพยากรนั้น มันง่ายเหมือน JSON นี้

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}

เซิร์ฟเวอร์จะหาวิธีรับจากสถานะปัจจุบัน (พูดว่า "กำลังทำงาน") ถึงสถานะ / รัฐ "หยุดชั่วคราว"

หากไคลเอนต์ทำ GET บนทรัพยากรมันควรจะกลับสู่สถานะที่เป็นอยู่ในปัจจุบัน (พูดว่า "หยุดชั่วคราว")

เหตุผลในการทำเช่นนี้และสาเหตุที่ REST มีประสิทธิภาพมากคือคุณปล่อยให้ HOW รับสถานะนั้นในเซิร์ฟเวอร์

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

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


2
เท่าที่ฉันกังวลนี่คือคำตอบที่ถูกต้อง การรีเฟรชข้อมูลบนเซิร์ฟเวอร์ไม่ใช่การดำเนินการ idempotent และGETเป็นคำกริยาที่ไม่เหมาะสมอย่างสมบูรณ์ที่จะใช้ PUTเป็นคำกริยาที่เหมาะสมที่สุดเนื่องจากการดำเนินการสามารถคิดได้ว่าเป็นการอัปเดต "สถานะการโหลดซ้ำ" ของแคชเป็น "โหลดซ้ำ"
Jez

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

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

... ถึงแม้ว่าฉันคิดว่าฉันชอบ POST ถึง PUT ในกรณีนี้เนื่องจาก PUT ควรจะเป็น idempotent ด้วยเช่นกัน แต่ POST ไม่มีข้อ จำกัด เช่นนี้
Craig

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

32

บางคำตอบอื่น ๆ รวมถึงคำตอบที่ได้รับการแนะนำให้คุณใช้ GET (แม้ว่าจะไม่ค่อยกระตือรือร้น)

ฉันไม่เห็นด้วย.

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

คุณมี RPC (การเรียกขั้นตอนระยะไกล) ซึ่งไม่สงบ - ​​คุณต้องการทำบางสิ่งบางอย่างบนเซิร์ฟเวอร์ ดังนั้นหากคุณพยายามสร้าง RESTful API อย่างแท้จริงคุณควรพิจารณาสิ่งที่คุณทำ

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

ถ้าคุณทำฉันจะแนะนำ PUT หรือ POST ขึ้นอยู่กับว่า RPC นั้นเป็นidempotentหรือไม่

โดยทั่วไปเราบอกว่า HTTP PUT จับคู่กับ SQL UPDATE และ HTTP POST จับคู่กับ SQL INSERT แต่นั่นไม่ได้เป็นเรื่องจริง วิธีที่บริสุทธิ์กว่าในการระบุว่า HTTP PUT ควรเป็น idempotent และ HTTP POST ไม่จำเป็นต้องเป็น ซึ่งหมายความว่าคุณสามารถเรียกคำขอ PUT เดียวกันได้หลายครั้งตามที่คุณต้องการโดยไม่มีผลข้างเคียง เมื่อคุณโทรครั้งเดียวมันจะไม่เป็นอันตรายต่อการโทรอีกครั้ง แต่คุณไม่ควรเรียกคำขอ POST ซ้ำ ๆ เว้นแต่คุณจะหมายถึง - POST แต่ละรายการจะเปลี่ยนข้อมูลบนเซิร์ฟเวอร์อีกครั้ง

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


6

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

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

  • การอัปเดตทั้งหมดผ่าน REST
  • เปิดเผยคำสั่งไปยังช่องทางอื่น
  • การดำเนินการอัตโนมัติ

ตัวเลือกบางอย่างอาจไม่สามารถใช้งานได้ขึ้นอยู่กับข้อ จำกัด อื่น ๆ ที่มีอยู่

ดูเพิ่มเติมที่ " PUT กับ POST ใน REST "


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

@ RenatoDinhaniConceição: แม้จะไม่มี "ภายใน" ก็ยังคงมีกลิ่น มันอาจจะทำให้คุณต้องถามคำถามใหม่ว่าการออกแบบนั้นดีหรือไม่
outis

4

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

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


ดูการแก้ไขของฉัน "reload" ไม่ใช่คำสั่งที่ส่งคืนข้อมูล มันหมายถึงบริการเว็บ REST เอง โดยทั่วไปคำถามของฉันหมายถึงการเรียกการกระทำในบริการเว็บ REST ตัวอย่างอื่น ๆ อาจเป็น: email_queue/stop_sending_emails. ฉันแค่ให้คำสั่งกับสิ่งที่ใช้อินเทอร์เฟซสงบ
Renato Dinhani

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

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

3

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

สำหรับครูสอนศาสนาคุณอาจมี URL เฉพาะสำหรับเรื่องนั้น โปรดทราบว่าคุณสามารถขยายและบันทึกการกระทำจริงในฐานข้อมูล (หรือที่เก็บข้อมูลใด ๆ ) ด้วยวันที่สถานะผู้ใช้ ฯลฯ ... เพียงแค่ความคิดของฉันที่นี่

การทำงาน / การกระทำ / {action} ทั่วทั้งระบบ

การดำเนินการเฉพาะกับประเภททรัพยากร / actions / {resource} / {action}

การดำเนินการเฉพาะกับทรัพยากร / actions / {resource} / {id} / {action}

ในกรณีของคุณแคชอาจเป็นทั้งระบบ / actions / reload_cache


0

ฉันควรใช้กริยา HTTP ใดเพื่อกระตุ้นการดำเนินการในบริการเว็บ REST

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

HTML สามารถอธิบายคำขอ GET และ POST ในรูปแบบดั้งเดิมได้เท่านั้น ดังนั้นเราสามารถเริ่มค้นหาได้ที่นั่น

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

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

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

มันจะใช้ในการโหลดการกำหนดค่าแคช ฯลฯ

หากสิ่งเหล่านี้มีราคาแพงที่ต้องทำคุณอาจไม่ต้องการให้ลูกค้าส่งคำขอเหล่านี้ตามดุลยพินิจของตนเอง

POSTในทางตรงกันข้ามไม่มีข้อ จำกัด อย่างมีประสิทธิภาพ - นี่เป็นการลดสมมติฐานที่ลูกค้าทั่วไปได้รับอนุญาต คุณไม่ได้รับส่วนประกอบที่ทำคำขอ POST เก็งกำไรเพราะพวกเขาจะทำผิด - ไม่มีอะไรในมาตรฐานที่บอกว่าไม่เป็นไร

PUT, PATCH, DELETE... เหล่านี้เป็นวิธีการที่ไม่ปลอดภัยที่มีความหมายเฉพาะเจาะจงมากขึ้นกว่าPOST; ไม่ว่าจะเหมาะสมหรือไม่นั้นขึ้นอยู่กับรูปแบบทรัพยากรของคุณ

สิ่งสำคัญที่ควรทราบก็คือวิธีการ HTTP นั้นอยู่ในโดเมนเอกสาร (ดูการพูดคุยของ Jim Webber ในปี 2011 ) ผลกระทบที่คุณอธิบายอาจไม่ได้เป็นส่วนหนึ่งของโดเมนเอกสาร . สิ่งนี้จะช่วยให้คุณมีอิสระมากขึ้นในแง่ของวิธีการจัดระเบียบเอกสารของคุณเพื่อให้งานเสร็จ

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