แนวทางปฏิบัติที่ดีที่สุดสำหรับการอัพเดทบางส่วนในบริการ RESTful


208

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

ฉันไม่ต้องการให้ผู้โทรส่งเร็กคอร์ดทั้งหมดที่มีเพียงฟิลด์ที่อัปเดตด้วยเหตุผลด้านความปลอดภัย (มันรู้สึกเหมือน overkill)

มีวิธีที่แนะนำในการสร้าง URIs หรือไม่? เมื่ออ่าน REST หนังสือสไตล์ RPC โทรดูเหมือนจะขมวดคิ้ว

หากการโทรต่อไปนี้ส่งคืนระเบียนลูกค้าแบบเต็มสำหรับลูกค้าที่มี id 123

GET /customer/123
<customer>
    {lots of attributes}
    <status>ENABLED</status>
    {even more attributes}
</customer>

ฉันจะอัปเดตสถานะได้อย่างไร

POST /customer/123/status
<status>DISABLED</status>

POST /customer/123/changeStatus
DISABLED

...

อัปเดต : เพื่อเพิ่มคำถาม วิธีหนึ่งรวม 'การเรียกตรรกะทางธุรกิจ' ลงใน REST api อย่างไร มีวิธีที่ตกลงกันในการทำเช่นนี้? ไม่ใช่วิธีการทั้งหมดที่ CRUD โดยธรรมชาติ บางอันมีความซับซ้อนมากขึ้นเช่น ' sendEmailToCustomer (123) ', ' mergeCustomers (123, 456) ', ' countCustomers () '

POST /customer/123?cmd=sendEmail

POST /cmd/sendEmail?customerId=123

GET /customer/count 

3
หากต้องการตอบคำถามของคุณเกี่ยวกับ "การเรียกตรรกะทางธุรกิจ" นี่คือโพสต์เกี่ยวกับPOSTจาก Roy Fielding ตัวเอง: roy.gbiv.com/untangled/2009/it-is-okay-to-use-postโดยที่ความคิดพื้นฐานคือถ้าไม่มี 't วิธีการ (เช่นGETหรือPUT) POSTเหมาะกับการใช้งานการทำงานของคุณ
rojoca

นี่เป็นสิ่งที่ฉันทำลงไป โทรหา REST เพื่อดึงข้อมูลและอัพเดตทรัพยากรที่รู้จักโดยใช้ GET, PUT, DELETE POST สำหรับการเพิ่มทรัพยากรใหม่และ POST ด้วย URL อธิบายสำหรับการโทรลอจิกธุรกิจ
magiconair

สิ่งที่คุณตัดสินใจหากการดำเนินการนั้นไม่ได้เป็นส่วนหนึ่งของการตอบกลับของ GET คุณจะไม่มีบริการ RESTful ฉันไม่เห็นสิ่งนี้ที่นี่
MStodd

คำตอบ:


69

โดยทั่วไปคุณมีสองตัวเลือก:

  1. ใช้PATCH(แต่โปรดทราบว่าคุณต้องกำหนดประเภทสื่อของคุณเองที่ระบุสิ่งที่จะเกิดขึ้นอย่างแน่นอน)

  2. ใช้POSTกับรีซอร์สย่อยและส่งคืน 303 โปรดดูอื่น ๆ ที่มีส่วนหัว Location ที่ชี้ไปยังรีซอร์สหลัก ความตั้งใจของ 303 คือการบอกลูกค้า: "ฉันได้ทำ POST ของคุณแล้วและผลกระทบก็คือทรัพยากรอื่น ๆ บางส่วนได้รับการอัปเดตดูที่ส่วนหัวสถานที่ตั้งซึ่งเป็นทรัพยากร" POST / 303 มีไว้สำหรับการเพิ่มเติมซ้ำไปยังแหล่งข้อมูลเพื่อสร้างสถานะของทรัพยากรหลักบางอย่างและเหมาะอย่างยิ่งสำหรับการปรับปรุงบางส่วน


ตกลง POST / 303 เหมาะสมกับฉัน PATCH และ MERGE ฉันไม่พบคำกริยา HTTP ที่ถูกต้องในรายการที่ต้องการการทดสอบเพิ่มเติม ฉันจะสร้าง URI ได้อย่างไรหากฉันต้องการให้ระบบส่งอีเมลไปยังลูกค้า 123 บางอย่างเช่นการเรียกใช้เมธอด RPC บริสุทธิ์ที่ไม่เปลี่ยนสถานะของวัตถุเลย RESTful วิธีการทำเช่นนี้คืออะไร?
magiconair

ฉันไม่เข้าใจคำถามอีเมลของ URI คุณต้องการติดตั้งเกตเวย์ที่คุณสามารถใช้โพสต์เพื่อให้ส่งอีเมลหรือคุณกำลังมองหา mailto: customer.123@service.org?
Jan Algermissen

15
REST และ HTTP ไม่มีส่วนเกี่ยวข้องกับ CRUD นอกเหนือจากบางคนที่ใช้วิธี HTTP กับ CRUD REST เป็นเรื่องเกี่ยวกับการจัดการสถานะทรัพยากรโดยการโอนการรับรอง ไม่ว่าคุณต้องการทำอะไรให้สำเร็จด้วยการโอนการเป็นตัวแทนไปยังทรัพยากรที่มีความหมายที่เหมาะสม ระวังคำว่า 'การเรียกเมธอดบริสุทธิ์' หรือ 'ตรรกะทางธุรกิจ' เนื่องจากพวกเขาบอกเป็นนัยได้ง่ายว่า 'HTTP for the transport' หากคุณต้องการส่งอีเมล POST ไปยังทรัพยากรเกตเวย์หากคุณต้องการรวมเข้ากับบัญชีสร้างบัญชีใหม่และเป็นตัวแทน POST ของอีกสองรายการ ฯลฯ
Jan Algermissen

9
ดูเพิ่มเติมว่า Google ทำอย่างไร: googlecode.blogspot.com/2010/03/…
Marius

4
williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot PATCH [{"op": "ทดสอบ", "เส้นทาง": "/ a / b / c", "ค่า" : "foo"}, {"op": "remove", "path": "/ a / b / c"}, {"op": "เพิ่ม", "path": "/ a / b / c" , "value": ["foo", "bar"]}, {"op": "replace", "path": "/ a / b / c", "value": 42}, {"op": "ย้าย", "จาก": "/ a / b / c", "เส้นทาง": "/ a / b / d"}, {"op": "คัดลอก", "จาก": "/ a / b / d "," path ":" / a / b / e "}]
intotecho

48

คุณควรใช้ POST สำหรับการอัพเดทบางส่วน

หากต้องการอัปเดตฟิลด์สำหรับลูกค้า 123 ให้ทำ POST เป็น / ลูกค้า / 123

หากคุณต้องการอัปเดตเฉพาะสถานะคุณสามารถใส่เป็น / ลูกค้า / 123 / สถานะ

โดยทั่วไปคำขอ GET ไม่ควรมีผลข้างเคียงใด ๆ และ PUT ใช้สำหรับการเขียน / แทนที่ทรัพยากรทั้งหมด

สิ่งนี้ติดตามได้โดยตรงจาก HTTP ดังที่เห็นที่นี่: http://en.wikipedia.org/wiki/HTTP_PUT#Request_methods


1
@John Saunders POST ไม่จำเป็นต้องสร้างทรัพยากรใหม่ที่สามารถเข้าถึงได้จาก URI: tools.ietf.org/html/rfc2616#section-9.5
wsorenson

10
@wsorensen: ฉันรู้ว่าไม่จำเป็นต้องมี URL ใหม่ แต่ยังคิดว่า POST /customer/123ควรสร้างสิ่งที่ชัดเจนซึ่งมีเหตุผลภายใต้ลูกค้า 123 อาจเป็นคำสั่งซื้อหรือไม่ ใส่ลงไป/customer/123/statusดูเหมือนจะทำให้รู้สึกที่ดีกว่าสมมติว่าโพสต์เพื่อ/customersสร้างstatus(และสมมติว่าเป็นส่วนที่ถูกต้องตามกฎหมายโดยปริยาย)
John Saunders

1
@John Saunders: พูดจริงถ้าเราต้องการอัปเดตฟิลด์ในทรัพยากรที่ตั้งอยู่ใน URI ที่กำหนด POST มีความหมายมากกว่า PUT และขาดการอัปเดตฉันเชื่อว่ามันมักใช้ในบริการ REST โพสต์ถึง / ลูกค้าอาจสร้างลูกค้าใหม่และสถานะ PUT ถึง / ลูกค้า / 123 / อาจสอดคล้องกับข้อกำหนดของสเปคได้ดีกว่า แต่สำหรับแนวทางปฏิบัติที่ดีที่สุดฉันไม่คิดว่าจะมีเหตุผลใด ๆ ที่จะไม่โพสต์ถึง / ลูกค้า / 123 เพื่ออัปเดตฟิลด์ - กระชับกระชับเข้าท่าและไม่ขัดกับอะไรในสเปค
wsorenson

8
คำขอ POST ไม่ควรเป็น idempotent หรือไม่ แน่นอนการอัพเดตรายการเป็น idempotent และควรเป็น PUT แทน
Martin Andersson

1
@MartinAndersson - POSTคำขอไม่จำเป็นต้องไม่ใช่ idempotent และดังกล่าวPUTจะต้องแทนที่ทรัพยากรทั้งหมด
Halle Knast

10

คุณควรใช้ PATCH สำหรับการอัพเดทบางส่วน - อาจใช้เอกสาร json-patch (ดูที่http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-08หรือhttp://www.mnot.net/ บล็อก / 2012/09/05 / patch ) หรือเฟรมเวิร์กแพตช์ XML (ดูที่http://tools.ietf.org/html/rfc5261 ) ในความคิดของฉัน json-patch นั้นเหมาะสมที่สุดสำหรับข้อมูลธุรกิจของคุณ

PATCH กับเอกสารแก้ไขแพทช์ JSON / XML มีความหมายที่เข้มงวดมากสำหรับการอัพเดทบางส่วน หากคุณเริ่มใช้ POST พร้อมสำเนาที่แก้ไขแล้วของเอกสารต้นฉบับสำหรับการอัปเดตบางส่วนในไม่ช้าคุณจะพบปัญหาที่คุณต้องการค่าที่หายไป (หรือแทนค่า Null) เพื่อแสดง "ละเว้นคุณสมบัตินี้" หรือ "ตั้งค่าคุณสมบัตินี้เป็น ค่าที่ว่างเปล่า "- และนั่นนำไปสู่โพรงกระต่ายของโซลูชันที่ถูกแฮ็กซึ่งท้ายที่สุดจะส่งผลในรูปแบบแพตช์ของคุณเอง

คุณสามารถหาคำตอบเพิ่มเติมในเชิงลึกที่นี่: http://soabits.blogspot.dk/2013/01/http-put-patch-or-post-partial-updates.html


โปรดทราบว่าในขณะเดียวกัน RFC สำหรับjson-patchและxml-patchได้รับการสรุปแล้ว
botchniaque

8

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

นี่เป็นวิธีแก้ปัญหาสองข้อที่ฉันนึกได้:

  1. ทำ PUT กับทรัพยากรทั้งหมด บนฝั่งเซิร์ฟเวอร์ให้กำหนดซีแมนทิกส์ที่ PUT ที่มีทรัพยากรทั้งหมดจะละเว้นค่าทั้งหมดที่ไม่ได้เปลี่ยนแปลง

  2. ทำ PUT ด้วยทรัพยากรบางส่วน ที่ฝั่งเซิร์ฟเวอร์ให้กำหนดซีแมนติกส์ของสิ่งนี้เพื่อรวม

2 เป็นเพียงการเพิ่มประสิทธิภาพแบนด์วิดท์ของ 1 บางครั้ง 1 เป็นตัวเลือกเดียวหากทรัพยากรกำหนดบางฟิลด์เป็นฟิลด์บังคับ (คิดว่าบัฟเฟอร์โปรโต)

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

ความคิดเห็น?


2
สิ่งนี้จะมีประโยชน์มากขึ้นหากโพสต์เป็นคำถามแยกต่างหาก
intotecho

6

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

ตัวอย่าง:

POST /customer/active  <-- Providing entity in the body a new customer
{
  ...  // attributes here except status
}

บริการ POST ควรส่งคืนลูกค้าที่สร้างขึ้นใหม่ด้วยรหัส:

{
    id:123,
    ...  // the other fields here
}

GET สำหรับทรัพยากรที่สร้างขึ้นจะใช้ตำแหน่งของทรัพยากร:

GET /customer/123/active

GET / ลูกค้า / 123 / ไม่ได้ใช้งานควรกลับ 404

สำหรับการดำเนินการ PUT โดยไม่ต้องระบุเอนทิตี Json เพียงแค่อัปเดตสถานะ

PUT /customer/123/inactive  <-- Deactivating an existing customer

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

PUT /customer/123/inactive
{
    ...  // entity fields here except id and status
}

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

การดำเนินการอ่าน:

GET /customer/123/active 
GET /customer/123/inactive

หากคุณทำการโทรหนึ่งครั้งหลังจากที่อีกสายหนึ่งนั้นต้องส่งคืนสถานะ 404 ผลลัพธ์ที่สำเร็จอาจไม่รวมถึงสถานะตามที่เป็นนัย แน่นอนคุณยังสามารถใช้ GET / customer / 123? status = ACTIVE | INACTIVE เพื่อค้นหาทรัพยากรของลูกค้าโดยตรง

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

DELETE /customer/123/active

ลูกค้าสามารถพาลูกค้าของคุณไปยังสถานะลบ / ปิดการใช้งานหรือสถานะตรงกันข้าม (ใช้งาน / ไม่ทำงาน)


คุณจะไปยังทรัพยากรย่อยได้อย่างไร
MStodd

ฉันปรับโครงสร้างคำตอบที่พยายามทำให้ชัดเจนยิ่งขึ้น
raspacorp

5

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

การส่งจดหมาย


POST /customers/123/mails

payload:
{from: x@x.com, subject: "foo", to: y@y.com}

การใช้งานทรัพยากรนี้ + POST จะส่งจดหมายออกไป หากจำเป็นคุณสามารถเสนอสิ่งที่ต้องการ / customer / 123 / outbox และเสนอลิงค์ทรัพยากรไปยัง / customer / mails / {mailId}

จำนวนลูกค้า

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


GET /customers

response payload:
{numFound: 1234, paging: {self:..., next:..., previous:...} customer: { ...} ....}


ฉันชอบวิธีการจัดกลุ่มเชิงตรรกะของเขตข้อมูลในทรัพยากรย่อย POST
gertas

3

ใช้ PUT เพื่ออัปเดตทรัพยากรที่ไม่สมบูรณ์ / บางส่วน

คุณสามารถยอมรับ jObject เป็นพารามิเตอร์และวิเคราะห์ค่าเพื่ออัพเดตรีซอร์ส

ด้านล่างเป็นฟังก์ชั่นที่คุณสามารถใช้เป็นข้อมูลอ้างอิงได้:

public IHttpActionResult Put(int id, JObject partialObject)
{
    Dictionary<string, string> dictionaryObject = new Dictionary<string, string>();

    foreach (JProperty property in json.Properties())
    {
        dictionaryObject.Add(property.Name.ToString(), property.Value.ToString());
    }

    int id = Convert.ToInt32(dictionaryObject["id"]);
    DateTime startTime = Convert.ToDateTime(orderInsert["AppointmentDateTime"]);            
    Boolean isGroup = Convert.ToBoolean(dictionaryObject["IsGroup"]);

    //Call function to update resource
    update(id, startTime, isGroup);

    return Ok(appointmentModelList);
}

2

เกี่ยวกับการอัปเดตของคุณ

แนวคิดของ CRUD ฉันเชื่อว่าทำให้เกิดความสับสนเกี่ยวกับการออกแบบ API CRUD เป็นแนวคิดระดับต่ำทั่วไปสำหรับการดำเนินการขั้นพื้นฐานเพื่อดำเนินการกับข้อมูลและคำกริยา HTTP เป็นเพียงวิธีการร้องขอ ( สร้างเมื่อ 21 ปีที่แล้ว ) ที่อาจหรือไม่อาจแมปกับการดำเนินการ CRUD ในความเป็นจริงลองค้นหาการมีอยู่ของตัวย่อ CRUD ในข้อมูลจำเพาะ HTTP 1.0 / 1.1

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

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

นอกจากนี้ยังกล่าวว่าเมื่อการดำเนินการไม่ map ว่าด้วยวิธีการมาตรฐาน ( List, Get, Create, Update, Deleteในกรณีนี้) คนหนึ่งอาจใช้ "วิธีการที่กำหนดเอง" เหมือนที่ดึงวัตถุขึ้นอยู่กับหลายวัตถุการป้อนรหัสหลายหรือBatchGetSendEmail


2

RFC 7396 : JSON Merge Patch (เผยแพร่สี่ปีหลังจากคำถามถูกโพสต์) อธิบายวิธีปฏิบัติที่ดีที่สุดสำหรับ PATCH ในแง่ของรูปแบบและกฎการประมวลผล

โดยสรุปคุณส่ง HTTP PATCH ไปยังทรัพยากรเป้าหมายด้วยแอปพลิเคชัน / merge-patch + json MIME และชนิดเนื้อหาที่แสดงเฉพาะส่วนที่คุณต้องการที่จะเปลี่ยน / เพิ่ม / ลบแล้วปฏิบัติตามกฎการประมวลผลด้านล่าง

กฎ :

  • หากแพทช์ผสานที่จัดให้มีสมาชิกที่ไม่ปรากฏภายในเป้าหมายสมาชิกเหล่านั้นจะถูกเพิ่ม

  • หากเป้าหมายมีสมาชิกอยู่ค่าจะถูกแทนที่

  • ค่า Null ในแพทช์ผสานได้รับความหมายพิเศษเพื่อระบุการลบค่าที่มีอยู่ในเป้าหมาย

ตัวอย่างกรณีทดสอบที่แสดงกฎด้านบน (ดังที่เห็นในภาคผนวกของ RFC นั้น):

 ORIGINAL         PATCH           RESULT
--------------------------------------------
{"a":"b"}       {"a":"c"}       {"a":"c"}

{"a":"b"}       {"b":"c"}       {"a":"b",
                                 "b":"c"}
{"a":"b"}       {"a":null}      {}

{"a":"b",       {"a":null}      {"b":"c"}
"b":"c"}

{"a":["b"]}     {"a":"c"}       {"a":"c"}

{"a":"c"}       {"a":["b"]}     {"a":["b"]}

{"a": {         {"a": {         {"a": {
  "b": "c"}       "b": "d",       "b": "d"
}                 "c": null}      }
                }               }

{"a": [         {"a": [1]}      {"a": [1]}
  {"b":"c"}
 ]
}

["a","b"]       ["c","d"]       ["c","d"]

{"a":"b"}       ["c"]           ["c"]

{"a":"foo"}     null            null

{"a":"foo"}     "bar"           "bar"

{"e":null}      {"a":1}         {"e":null,
                                 "a":1}

[1,2]           {"a":"b",       {"a":"b"}
                 "c":null}

{}              {"a":            {"a":
                 {"bb":           {"bb":
                  {"ccc":          {}}}
                   null}}}

1

ตรวจสอบhttp://www.odata.org/

มันกำหนดวิธีการรวมกันดังนั้นในกรณีของคุณมันจะเป็นดังนี้:

MERGE /customer/123

<customer>
   <status>DISABLED</status>
</customer>

มีการstatusปรับปรุงคุณสมบัติเท่านั้นและค่าอื่น ๆ จะถูกเก็บไว้


เป็นMERGEคำกริยา HTTP ถูกต้อง?
John Saunders

3
ดูที่ PATCH ซึ่งเร็ว ๆ นี้จะเป็น HTTP มาตรฐานและทำสิ่งเดียวกัน
Jan Algermissen

@John Saunders ใช่มันเป็นวิธีการขยาย
Max Toro

FYI MERGE ถูกลบออกจาก OData v4 แล้ว MERGE was used to do PATCH before PATCH existed. Now that we have PATCH, we no longer need MERGE. ดูdocs.oasis-open.org/odata/new-in-odata/v4.0/cn01/…
tanguy_k

0

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

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

{
  "customer" :
  {
  },
  "operations":
  [
    "update" : 
    {
      "method": "POST",
      "href": "https://server/customer/123/"
    }]
}

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

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

"email":
{
  "method": "POST",
  "href": "http://server/emailservice/send?customer=1234"
}

วิดีโอที่ดีและตัวอย่างของสถาปัตยกรรม REST ของผู้นำเสนอเป็นสิ่งเหล่านี้ Stormpath ใช้ GET / POST / DELETE เท่านั้นซึ่งใช้ได้เนื่องจาก REST ไม่มีส่วนเกี่ยวข้องกับการดำเนินการที่คุณใช้หรือวิธีที่ URL ควรดู (ยกเว้น GETs ควรแคช):

https://www.youtube.com/watch?v=pspy1H6A3FM ,
https://www.youtube.com/watch?v=5WXYw4J4QOU ,
http://docs.stormpath.com/rest/quickstart/

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