REST - แลกเปลี่ยนระหว่างการเจรจาต่อรองเนื้อหาผ่านส่วนหัวยอมรับกับส่วนขยาย


40

ฉันกำลังทำงานผ่านการออกแบบ RESTful API เรารู้ว่าเราต้องการส่งคืน JSON และ XML สำหรับทรัพยากรที่กำหนด ฉันคิดว่าเราจะทำสิ่งนี้:

GET /api/something?param1=value1
Accept:  application/xml (or application/json)

อย่างไรก็ตามมีบางคนที่ใช้ส่วนขยายสำหรับสิ่งนี้เช่น:

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

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


เว็บเซิร์ฟเวอร์ใดที่คุณใช้อยู่ และมันแยกวิเคราะห์ URL อย่างไร
Dipan Mehta

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

@Dipan ฉันกำลังแฮ็คข้อมูลนี้ด้วย MVC4 Web API (ยังอยู่ในช่วงเบต้า) มันใช้ abstractions routing ของ ASP.NET ซึ่งค่อนข้างดี
แบรนดอนลินตัน

1
@Treb ใช่ฉันเป็นแฟนตัวยงของการใช้ค่าส่วนหัวที่ยอมรับได้ ฉันสงสัยว่ามีข้อเสียเปรียบในการสนับสนุนทั้งสองหรือไม่
แบรนดอนลินตัน

คำตอบ:


38

นี่คือ "อย่างไรก็ตามตามหลักปรัชญา - แนวทางแรกเป็นแนวทางเดียว" และ "วิธีการ RESTful อย่างเป็นทางการที่เหมาะสมคือใช้ยอมรับ: ส่วนหัว" เป็นที่รับรู้กันอย่างแพร่หลายจะเป็นกรณีที่ แต่ยังไม่ถูกต้องอย่างแน่นอน

นี่เป็นตัวอย่างสั้น ๆ จาก Roy Fielding (ผู้ที่กำหนด REST) ​​...

"ส่วน 6.2.1 ไม่ได้บอกว่าควรใช้การเจรจาต่อรองเนื้อหาตลอดเวลา" อ้างอิง

การสนทนาเฉพาะนั้นอยู่ในบริบทของส่วนหัว 'ยอมรับภาษา:' แต่การสนทนานั้นใช้กับส่วนหัว 'ยอมรับ:' เท่ากันตามที่ได้อธิบายไว้ในภายหลังในการตอบกลับของเขา ...

"ฉันไม่รู้ว่าทำไมคนไม่เห็นลิงค์ที่สองและสามในหน้าบนสุด

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

ชี้ไปที่ทั้งสองฉบับ PDF "

สิ่งที่เขาหมายความว่าไม่มีปัญหาในการใช้จุดปลายที่แตกต่างกันสำหรับการรับรองที่แตกต่างกันของแหล่งข้อมูลเดียวกัน (ในกรณีนี้หนึ่ง. html endpoint และสอง. pdf ปลายทางที่แตกต่างกัน)

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

"นั่นเป็นสาเหตุที่ฉันมักจะชอบส่วนขยายเสมอไม่มีตัวเลือกใด ๆ ที่เกี่ยวข้องกับ REST" อ้างอิง

อีกครั้งที่แตกต่างกันเล็กน้อยในการยอมรับกับนามสกุลไฟล์ แต่ท่าทางของฟีลดิงยังคงชัดเจน

คำตอบ - มันไม่สำคัญอะไรมาก การแลกเปลี่ยนระหว่างคนทั้งสองไม่สำคัญมากและทั้งคู่เป็นสไตล์ที่ยอมรับได้


3
คำตอบที่ยอดเยี่ยม ฉันคิดว่าฉันจะเพิ่มบางครั้งมันก็ 'ชัดเจน' จาก URI ว่าเนื้อหาบางอย่างตั้งใจ เช่น. html extension หรือ .pdf extension ใน URI และในกรณีนี้ไม่จำเป็นต้องสนับสนุนการเจรจาต่อรองเนื้อหาและการมีเนื้อหาโดยนัยใน URI ทำให้มนุษย์แบ่งปัน URI ได้ง่ายขึ้นและใช้เพื่อเชื่อมโยงกับสิ่งต่าง ๆ ในแบบที่พวกเขาสามารถบริโภคได้ทันที ในกรณีอื่น ๆ เช่นคุณต้องการหลีกเลี่ยงส่วนขยายใน URIs ของคุณและ / หรือคุณต้องการแสดงเว็บ API ที่รองรับประเภทเนื้อหาหลายประเภท json / XML เท่า ๆ กันส่วนหัวการยอมรับอาจเหมาะสมกว่า
Tim Lovell-Smith

อัปเดตคำตอบเพื่อให้มีลิงก์ใหม่ ฉันคิดว่ากลุ่ม yahoo เปลี่ยนโครงสร้างของพวกเขาไปรอบ ๆ
Phil Sturgeon

ฉันไม่เห็นด้วย. ภาษาคำอธิบายทรัพยากรที่ส่งคืนโดยเซิร์ฟเวอร์ควรไม่เกี่ยวข้องกับตรรกะทางธุรกิจที่ดำเนินการโดยจุดสิ้นสุดบริการ การมี URI หลายแห่งสำหรับจุดบริการเดียวกันเพียงเพื่อรองรับภาษาคำอธิบายทรัพยากรที่แตกต่างกันดูเหมือนจะเข้าใจผิดว่า REST URIs ควรสร้างอย่างไร
Dejay Clayton

10

วิธี RESTful อย่างเป็นทางการที่เหมาะสมคือการใช้Accept:ส่วนหัว

อย่างไรก็ตามคุณต้องระวังไม่ทำลายแคชซึ่งเป็นหนึ่งในข้อกำหนดของ REST คุณต้องมีVary: Acceptส่วนหัวและแคชที่เข้าใจได้ ในโลกอุดมคติที่คุณมี แต่ในชีวิตจริงค่าจ้างของคุณอาจแตกต่างกันไป ดังนั้นวิธีที่สองนั้นไม่สะอาด แต่อาจใช้ได้มากกว่า

นอกจากนี้โปรดทราบว่าเบราว์เซอร์เก่า ๆ บางตัวเคยใช้ที่จะไม่ใช้ส่วนหัวโดยใช้ส่วนขยายแทน


1
ความจริงที่ไม่ถูกต้อง ดูคำตอบที่ยอมรับได้
Phil Sturgeon

9

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

อย่างไรก็ตามทางปรัชญา - แนวทางแรกคือแนวทางเดียว ใน REST URL จะชี้ไปยัง URI เท่านั้นซึ่งเป็นเพียงแหล่งข้อมูลเท่านั้น คิดสักครู่ว่าทรัพยากรนี้เหมือนกับวัตถุในการเขียนโปรแกรมเชิงวัตถุ คุณพูดคุยกับทรัพยากรนี้ด้วยวิธีการเพียง 4 วิธี (aka GET / POST / PUT / DELETE - หรือหากสิ่งใดก็ตามที่อนุญาตให้มีการขนส่ง) แต่วิธีการนั้นไม่ได้กลายเป็นคำอธิบายของวัตถุ เช่นเดียวกันกับแง่มุมที่ค่าส่งคืนไม่ใช่ URI วัตถุยังคงเป็นบางสิ่งและไม่ใช่something.xmlหรือsomething.json

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

GET /api/something?parm1=value1&return_type=xml

ตรงข้ามกับ

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

แต่อย่างที่ฉันพูดความแตกต่างนี้เป็นเพียงปรัชญาเท่านั้น


1 Dipan คุณมีสิทธิยกเว้นสิ่งหนึ่งที่:? / API / บางสิ่งบางอย่าง return_type = XML เป็นยังไม่พักผ่อน เหตุผลที่ไม่สงบเนื่องจาก URL นั้นทึบ IOW จากมุมมองโปรโตคอลไม่มีความแตกต่างระหว่าง / api / something / xml และ / api / something? xml ดูw3.org/DesignIssues/Axioms.html
Mark E. Haase

0

@vartec: ฉันคิดว่าคุณผิด

หลักการ RESTful อย่างเป็นทางการที่เหมาะสมกล่าวว่าไม่มีสิ่งใดควรซ่อนอยู่ในส่วนหัว HTTP เนื่องจากเป็น URI ที่ถูกเปิดเผยหรือมีการอ้างอิงรายละเอียดใด ๆ เกี่ยวกับการร้องขอ / การตอบสนองควรเป็นส่วนหนึ่งของ URI

ดังนั้นฉันขอแนะนำอย่างยิ่งให้หลีกเลี่ยงการใช้ส่วนหัวเพื่อดูรายละเอียดเกี่ยวกับคำขอและการตอบกลับและดำเนินการต่อ

 GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

ฉันไม่สามารถหาข้อมูลอ้างอิงได้อย่างรวดเร็ว แต่ฉันจะโพสต์กลับไปด้วย (จริง ๆ แล้วคุณสามารถอ้างอิงหนังสือตีพิมพ์ของ O'reilly "บริการเว็บสงบ" ( http://shop.oreilly.com/product/9780596529260.do ) ซึ่งยืนยันเหมือนกัน


17
-1 ผิดโดยสิ้นเชิง ประการหนึ่ง URL จะถูกส่งในส่วนหัว HTTP นอกจากนี้แต่ละ URL ที่แตกต่างกันควรแสดงถึงทรัพยากรที่แตกต่างกัน การเข้ารหัส XML และ JSON ของเนื้อหาเดียวกันนั้นไม่ใช่แหล่งข้อมูลที่แตกต่างกัน 2 แหล่งอย่างชัดเจน พวกเขาเป็นตัวแทนที่แตกต่างกัน 2 ของทรัพยากรเดียวกัน
Mark E. Haase

ส่วนหัว HTTP เป็นสถานที่ที่ถูกต้องตามกฎหมายและแนะนำให้เก็บ "ข้อมูลเมตาการส่งข้อความ" เช่น: ข้อมูลรับรองความปลอดภัย, ตัวระบุความสัมพันธ์, รหัสเซสชัน, บริบทการทำธุรกรรม, รูปแบบข้อมูล ข้อมูลประเภทนี้ไม่ควรทำให้ URL ของคุณยุ่งเหยิงหรือเพย์โหลดข้อความของคุณ
เปาโลเมอร์สัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.