REST สามารถส่งคืนเนื้อหาหลังจาก POST ได้หรือไม่


89

ฉันใช้ RESTlet และฉันได้สร้างทรัพยากร ฉันจัดการ POST ด้วยacceptRepresentationวิธีการลบล้าง

ไคลเอนต์ควรส่งข้อมูลบางส่วนให้ฉันจากนั้นฉันเก็บไว้ที่ DB ตั้งค่าการตอบสนองเป็น 201 (SUCCESS_CREATED) และฉันต้องการส่งคืนข้อมูลบางส่วนให้กับไคลเอนต์ แต่ส่งคืนประเภทของ acceptRepresentationvoidคือ

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

ตัวอย่างเช่นถ้าผมมีทรัพยากรที่มี URL /resourceและลูกค้าส่งคำขอ POST /resource/{id}ฉันเพิ่มแถวใหม่ในฐานข้อมูลและที่อยู่ของมันควรจะเป็น ฉันต้องการส่ง{id}ฉันต้องการที่จะส่ง

ฉันทำอะไรผิดหรือเปล่า? หลักการ REST อนุญาตให้ส่งคืนบางสิ่งหลังจาก POST หรือไม่ ถ้าใช่ฉันจะทำอย่างไรและถ้าไม่มีวิธีจัดการกับสถานการณ์นี้คืออะไร?


ดูคำตอบของ Thom สำหรับวิธีตั้งค่าเนื้อหาตอบกลับจากภายใน acceptRepresentation ()
Avi Flax

คำตอบ:


97

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

หากทรัพยากรถูกสร้างขึ้นบนเซิร์ฟเวอร์ต้นทางการตอบสนองควรเป็น 201 (สร้าง) และมีเอนทิตีที่อธิบายสถานะของคำขอและอ้างถึงทรัพยากรใหม่และส่วนหัวตำแหน่ง (ดูหัวข้อ 14.30)

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

ฉันไม่แน่ใจว่าความแตกต่างระหว่างการลบล้าง acceptRepresentation () และการลบล้างโพสต์ () อย่างไร แต่ตัวอย่างนี้แสดงวิธีการตอบกลับจาก POST


2
@ del-boy: ดูคำตอบของ Thom สำหรับวิธีตั้งค่าเนื้อหาตอบกลับจากภายใน acceptRepresentation ()
Avi Flax

1
การอ้างข้อมูลจำเพาะของ HTTP ไม่ได้ห้ามการตอบสนองหากคุณดูในส่วนที่ 6 จะเห็นได้ชัดเจนว่า: Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.
MikeF

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

16

ฉันจะไม่ส่งอะไรก็ตามในเนื้อหาของการตอบสนอง เพียงตั้งค่า Location: เป็น URL (แบบเต็ม) ของทรัพยากรที่สร้างขึ้นใหม่

คำอธิบายของคุณแสดงให้เห็นว่านี่คือความหมายของคุณ:

  1. โพสต์สิ่งที่จะสร้างมัน
  2. ตอบแบบพอรู้สองอย่างคือ
    1. การสร้างนั้นเกิดขึ้น (ปี 201)
    2. จะหาสิ่งใหม่ได้ที่ไหน (ส่วนหัวตำแหน่ง)

สิ่งอื่นใดที่ไม่จำเป็น


ไม่ว่าวิกิพีเดียมักจะเป็นแหล่งที่ดี แต่ที่ยังเรียกร้อง"[ ... ] เพื่อให้ข้อมูลเกี่ยวกับสถานที่ตั้งของทรัพยากรที่สร้างขึ้นใหม่. ในกรณีนี้ส่วนหัวของสถานที่ที่ควรจะส่งไปพร้อมกับรหัสสถานะ HTTP 201 หรือ 202 .”
Arjan

1
POST อาจดำเนินการตรรกะที่สร้างทรัพยากรอย่างน้อยหนึ่งรายการ ลูกค้าอาจต้องการผลลัพธ์ของการประมวลผล ดังนั้นการส่งคืนในการตอบกลับจึงหลีกเลี่ยงความจำเป็นในการเรียก GET หนึ่งรายการขึ้นไปไปยัง API ข้อมูลที่สร้าง / เปลี่ยนแปลงโดยวิธีการ POST อาจไม่ (และมักไม่เป็นประโยชน์) ต่อไคลเอนต์
Paulo Merson

10

สองคำถามที่แตกต่างกัน:

รูปแบบแอปพลิเคชัน REST รองรับการส่งคืนข้อมูลใน POST หรือไม่

ฉันไม่คิดว่า REST ปิดการใช้งานอย่างชัดเจน แต่การรักษาที่ต้องการนั้นสะกดไว้ในคำตอบของ Darrel

เฟรมเวิร์ก RESTlet อนุญาตให้ส่งคืนข้อมูลใน POST หรือไม่

ใช่แม้ว่ามันจะคืนค่าเป็นโมฆะในคลาสที่ขยาย Resource คุณก็สามารถเข้าถึงอ็อบเจ็กต์ Response ได้อย่างสมบูรณ์ผ่านเมธอด getResponse () ดังนั้นคุณสามารถเรียก getResponse (). setEntity () ด้วยข้อมูลใดก็ได้ที่คุณต้องการ


6

ส่งออกในรูปแบบใดก็ได้ที่ร้องขอ นั่นอาจเป็น:

<success>
    <id>5483</id>
</success>

หรือ:

{ "type": "success", "id": 5483 }

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


โอเคฉันมีสองรูปแบบที่เป็นไปได้ (html และ xml) ฉันรู้วิธีจัดการประเภทของรูปแบบที่ร้องขอ แต่ไม่รู้วิธีเพิ่มข้อมูลในการตอบกลับ เป็นตัวแทนของวิธีการส่งกลับการเป็นตัวแทนดังนั้นฉันจึงส่งคืนสิ่งที่ฉันต้องการ แต่ยอมรับการแสดงเป็นโมฆะดังนั้นฉันจึงไม่สามารถส่งคืนข้อมูลใด ๆ ...
del-boy

1

หากคุณตอบสนอง 201 Created with an entity body แทนที่จะเป็นการเปลี่ยนเส้นทาง Location คุณควรรวมส่วนหัวของ Content-Location ที่ชี้ไปยังทรัพยากรที่จะแสดงในการตอบกลับ

สิ่งนี้จะหลีกเลี่ยงความสับสนที่อาจเกิดขึ้น - ซึ่งลูกค้าสามารถ (แก้ตัวได้) ว่าเอนทิตีการตอบกลับแสดงสถานะใหม่ของ 'ผู้สร้าง' ไม่ใช่ทรัพยากรที่สร้างขึ้น

> POST /collection
> ..new item..

< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>

3
ฉันคิดว่าเนื้อหา - สถานที่ตั้งมีวัตถุประสงค์อื่น ข้อมูลจำเพาะ HTTP ระบุว่า Content-Location ไม่ได้กำหนดไว้สำหรับ POST และ PUT ส่วนหัวตำแหน่งใช้กับ 201-Create การส่งคืนตำแหน่งไม่ได้ทำการเปลี่ยนเส้นทางโดยอัตโนมัติคุณต้องมีรหัสตอบกลับ 3XX สำหรับสิ่งนั้น
Darrel Miller

1
ใช้ส่วนหัวตำแหน่ง (ในการตอบกลับ 201) เพื่อระบุตำแหน่งของทรัพยากรที่สร้างขึ้น ไม่เกี่ยวข้องกับเนื้อหาของการตอบสนองที่มาพร้อมกับเอนทิตี ประเด็นของฉันคือ - ถ้าคุณต้องการรวมทรัพยากรที่สร้างขึ้นในการตอบสนอง 201 เอง (แทนที่จะกำหนดทิศทาง / เปลี่ยนเส้นทางไคลเอนต์ไปยัง URI อื่น) ส่วนหัวตำแหน่งเนื้อหาก็เป็นความคิดที่ดี นี่อาจเป็นการ 'ดัดกฎ' เล็กน้อย แต่มีประสิทธิภาพมากกว่าที่จะต้องใช้รอบการร้องขอ / การตอบกลับอื่นเพื่อให้ได้สถานะของทรัพยากรใหม่ไปยังไคลเอนต์
ไมค์

เข้าท่ากับฉัน ฉันไม่เคยใช้ส่วนหัวตำแหน่งเนื้อหามาก่อน
Darrel Miller

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

3
@irreputable: ฉันเชื่อว่า REST มีไว้สำหรับการออกแบบ API โดยที่ A ไม่ได้หมายถึง User Agent ซึ่งมองหา HTML เพื่อแสดงผล
Hermes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.