REST API นั้นเป็น RPC จริงหรือ Roy Fielding ดูเหมือนจะคิดอย่างนั้น


100

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

จากย่อหน้าแรกของREST APIของ Roy Fielding ต้องขับเคลื่อนด้วยไฮเปอร์เท็กซ์เป็นที่ชัดเจนว่าเขาเชื่อว่างานของเขาถูกตีความผิดอย่างกว้างขวาง:

ฉันรู้สึกไม่สบายใจกับจำนวนคนที่เรียกใช้อินเตอร์เฟสที่ใช้ HTTP เป็น REST API ตัวอย่างเช่นวันนี้เป็นSocialSite REST API นั่นคือ RPC มันกรีดร้อง RPC มีคลัปบนจอแสดงผลมากจนควรได้รับคะแนน X

Fielding จะแสดงรายการคุณลักษณะต่างๆของ REST API บางคนดูเหมือนจะขัดต่อแนวทางปฏิบัติทั่วไปและคำแนะนำทั่วไปใน SO และฟอรัมอื่น ๆ ตัวอย่างเช่น:

  • ควรป้อน REST API โดยไม่มีความรู้มาก่อนนอกเหนือจาก URI เริ่มต้น (บุ๊กมาร์ก) และชุดประเภทสื่อมาตรฐานที่เหมาะสมกับผู้ชมที่ต้องการ (กล่าวคือลูกค้าที่อาจใช้ API คาดว่าจะเข้าใจ) ...

  • REST API ต้องไม่กำหนดชื่อรีซอร์สถาวรหรือลำดับชั้น (การเชื่อมต่อระหว่างไคลเอนต์และเซิร์ฟเวอร์ที่ชัดเจน) ...

  • REST API ควรใช้ความพยายามในการอธิบายเกือบทั้งหมดในการกำหนดประเภทสื่อที่ใช้สำหรับแสดงทรัพยากรและขับเคลื่อนสถานะของแอปพลิเคชันหรือในการกำหนดชื่อความสัมพันธ์เพิ่มเติมและ / หรือมาร์กอัปที่เปิดใช้งานไฮเปอร์เท็กซ์สำหรับประเภทสื่อมาตรฐานที่มีอยู่ ...

แนวคิดของ "ไฮเปอร์เท็กซ์" มีบทบาทสำคัญมากกว่าโครงสร้าง URI หรือความหมายของคำกริยา HTTP "ไฮเปอร์เท็กซ์" ถูกกำหนดไว้ในหนึ่งในความคิดเห็น:

เมื่อฉัน [Fielding] พูดว่าไฮเปอร์เท็กซ์ฉันหมายถึงการนำเสนอข้อมูลพร้อมกันและการควบคุมเพื่อให้ข้อมูลกลายเป็นเงินที่ผู้ใช้ (หรืออัตโนมัติ) ได้รับทางเลือกและเลือกการดำเนินการ Hypermedia เป็นเพียงการขยายความหมายของข้อความในการรวมจุดยึดชั่วคราวไว้ในสตรีมสื่อ นักวิจัยส่วนใหญ่ลดความแตกต่าง

ไฮเปอร์เท็กซ์ไม่จำเป็นต้องเป็น HTML บนเบราว์เซอร์ เครื่องสามารถติดตามลิงก์ได้เมื่อเข้าใจรูปแบบข้อมูลและประเภทความสัมพันธ์

ฉันคาดเดา ณ จุดนี้ แต่สองประเด็นแรกข้างต้นดูเหมือนจะแนะนำว่าเอกสาร API สำหรับทรัพยากร Foo ที่มีลักษณะดังต่อไปนี้นำไปสู่การมีเพศสัมพันธ์ที่แน่นหนาระหว่างไคลเอนต์และเซิร์ฟเวอร์และไม่มีที่ใดในระบบ RESTful

GET   /foos/{id}  # read a Foo
POST  /foos/{id}  # create a Foo
PUT   /foos/{id}  # update a Foo

แต่ตัวแทนควรถูกบังคับให้ค้นหา URI สำหรับ Foos ทั้งหมดโดยตัวอย่างเช่นการออกคำขอ GET กับ / foos (URI เหล่านั้นอาจเป็นไปตามรูปแบบด้านบน แต่อยู่ข้างประเด็น) คำตอบใช้ประเภทสื่อที่สามารถถ่ายทอดวิธีการเข้าถึงแต่ละรายการและสิ่งที่สามารถทำได้โดยก่อให้เกิดประเด็นที่สามด้านบน . ด้วยเหตุนี้เอกสาร API จึงควรเน้นที่การอธิบายวิธีตีความไฮเปอร์เท็กซ์ที่อยู่ในการตอบกลับ

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

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

แต่นี่เป็นเพียงการคาดเดาที่ดีที่สุดของฉันในช่วงเวลานี้

ฟีลดิงโพสต์การติดตามผลซึ่งเขาตอบสนองต่อคำวิจารณ์ว่าการสนทนาของเขาเป็นนามธรรมเกินไปขาดตัวอย่างและมีศัพท์แสงที่หลากหลาย:

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

ดังนั้นคำถามง่ายๆสองข้อสำหรับผู้เชี่ยวชาญด้าน REST ที่มีแนวคิดที่ใช้ได้จริง: คุณตีความสิ่งที่ Fielding พูดอย่างไรและคุณนำไปปฏิบัติได้อย่างไรเมื่อจัดทำเอกสาร / ใช้งาน REST API

แก้ไข: คำถามนี้เป็นตัวอย่างของความยากลำบากในการเรียนรู้บางสิ่งหากคุณไม่มีชื่อสำหรับสิ่งที่คุณกำลังพูดถึง ชื่อในกรณีนี้คือ "Hypermedia as the Engine of Application State" (HATEOAS)


26
John, Rich กำลังอธิบายถึงการเปลี่ยนแปลงความคิดที่เขามี ไม่มีอะไรเป็นอัตวิสัยหรือโต้แย้งเกี่ยวกับเรื่องนี้ โหวตให้เปิด - เป็นหนึ่งในคำถามที่ดีกว่าที่ติดแท็ก "พักผ่อน" ที่ฉันเคยเห็นใน SO
Keith Gaughan

4
คี ธ "อธิบายถึงการเปลี่ยนแปลงความคิด" คือสิ่งที่เขาควรทำในบล็อกของเขาไม่ใช่ใน SO
John Saunders

13
เขาไม่ได้อธิบายถึงความคิดที่เปลี่ยนไปเขาถามว่าความเข้าใจของเขาถูกต้องหรือไม่
aehlke

4
สรุปยอดเยี่ยม. ฉันเรียนรู้เพิ่มเติมจากคำถามนี้มากกว่าจากคำตอบส่วนใหญ่
Martin Konecny

คำตอบ:


21

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

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

หากคุณบันทึก URI หรือวิธีการสร้างแสดงว่าคุณทำผิด


ยังมีอยู่จริงไหม มีข้อกำหนดการตอบสนองของ API เช่น Ionspec ซึ่งทำให้ URI เหล่านี้เป็นส่วนหนึ่งของการตอบสนองโดยเจตนา
Sean Pianka

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

สิ่งที่เป็นความจริงก็คือภาษาเอกสาร API จำนวนมากเกิดขึ้นในช่วง 11 ปีที่ผ่านมา แต่ปัจจัยพื้นฐานไม่ได้เปลี่ยนแปลง ฉันเชื่อว่าคุณค่าในการค้นพบลิงก์เหล่านั้นหรืออย่างน้อยที่สุดก็คือการค้นพบเทมเพลต URI คือการสร้างโค้ดไคลเอนต์ทั่วไปที่สามารถนำกลับมาใช้ใหม่ได้ซึ่งสามารถใช้โค้ดเหล่านี้ได้แบบไดนามิกทำให้การใช้งานจำนวนมากบนฝั่งเซิร์ฟเวอร์สามารถใช้โค้ดไคลเอ็นต์เดียวกันซ้ำได้ การฝัง URI ยังคงทำให้สถานการณ์ดังกล่าวยากขึ้น แต่ถ้าคุณใช้รูปแบบเหล่านั้นคุณมักจะจับคู่ไคลเอนต์ที่สร้างขึ้นจากข้อกำหนดเหล่านั้นอย่างแน่นหนาดังนั้นคุณจึงสูญเสียคุณสมบัตินั้นไปแล้ว
SerialSeb

"ถ้าลูกค้าคิดว่าทราบเนื่องจากสัญญานั้นคุณไม่ได้อยู่ในสื่อไฮเปอร์มีเดียคุณก็เข้าสู่รูปแบบสบู่โอเพนดาปิยุคใหม่พร้อมกับปัญหาเดียวกับที่คุณเคยพบเมื่อ 18 ปีที่แล้ว" คุณสามารถอธิบายความหมายของสิ่งนี้ได้หรือไม่?
Sean Pianka

8

การตีความของคุณดูเหมือนถูกต้องสำหรับฉัน ฉันเชื่อว่าข้อ จำกัด ของ Fielding สามารถนำไปใช้ได้จริง

ฉันอยากเห็นใครบางคนเผยแพร่ตัวอย่างที่ดีเกี่ยวกับการจัดทำเอกสารอินเทอร์เฟซ REST มีตัวอย่างที่น่าสงสารมากมายมีตัวอย่างที่ใช้ได้เพื่อชี้ให้ผู้ใช้เห็นว่ามีค่ามาก


2
ว้าว. หน้าแบบจำลองทรัพยากรนั้นทำให้ตาของฉันฉีกขาด หวังว่านี่จะเป็นเทรนด์
Darrel Miller

เป็นเรื่องน่าเสียดายที่นี่เป็นเพียงตัวอย่างเดียวของ API บนเว็บ! ยิ่งไปกว่านั้นไม่มีตัวอย่างที่ดีของรหัสไคลเอ็นต์ที่เป็นไปตามหลักการเลย (ที่ฉันได้พบ)
jkp

1
@DarrelMiller แต่ประเภทสื่อเหล่านั้นไม่ "เฉพาะเจาะจง" เกินไปหรือ? สำหรับฉันแล้วดูเหมือนว่า API ของพวกเขาใช้เพียง MIME เดียวเท่านั้นapplication/jsonและรูปแบบทรัพยากรเป็นความสัมพันธ์อย่างแท้จริง ฉันเข้าใจแง่มุมนี้ของ REST ผิดหรือเปล่า? ฉันได้อ่าน หนึ่งในคำตอบ SO ของคุณซึ่งดูเหมือนจะชี้ให้เห็นว่าควรหลีกเลี่ยงสัญญา "แอตทริบิวต์เดียว" เหล่านั้น ...
edsioufi

2
@RichApodaca ลิงค์ของคุณเสียชีวิตด้วยโรคบิด web.archive.org/web/20170409132237/https://kenai.com/projects/…
forresthopkinsa

5

ฉันกำลังมองหาตัวอย่างที่ดีของ API ที่เขียนตาม HATEOAS และมีปัญหาในการค้นหา (ฉันพบว่าทั้ง SunCloud API และ AtomPub ใช้กับสถานการณ์ API "ปกติ" ได้ยาก) ดังนั้นฉันจึงลองสร้างตัวอย่างที่เป็นจริงในบล็อกของฉันตามคำแนะนำของ Roy Fieldings เกี่ยวกับความหมายของการใช้งาน REST ที่เหมาะสม ฉันพบว่ามันยากมากที่จะสร้างตัวอย่างแม้ว่ามันจะค่อนข้างง่ายในหลักการ (เพียงแค่สับสนเมื่อทำงานกับ API เมื่อเทียบกับหน้าเว็บ) ฉันได้รับสิ่งที่ Roy กำลังมีปัญหาและเห็นด้วยมันเป็นเพียงการปรับเปลี่ยนความคิดเพื่อนำไปใช้อย่างเหมาะสมสำหรับ API

ลองดู: ตัวอย่าง API โดยใช้ Rest


4

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

การสนทนาที่ดีเกี่ยวกับ REST และ HATEOAS ที่เกี่ยวข้อง:

ข้อดีของการใช้ HATEOAS ใน RESTFul API

วิธีรับกาแฟสักแก้ว



4

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


2

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

ตาม Richardson Maturity Model มี 4 ระดับ (0-3) ที่กำหนดว่า RESTful API ของคุณเป็นอย่างไรโดย 3 หมายถึง RESTful API อย่างแท้จริงเช่นเดียวกับที่ Roy Fielding ตั้งใจให้เป็น

ระดับ 0 คือเมื่อคุณมี URI จุดเข้าหนึ่งจุดเช่น SOAP

ระดับ 1 หมายถึง API สามารถแยกความแตกต่างระหว่างทรัพยากรต่างๆและมีจุดเข้าใช้งานมากกว่าหนึ่งจุด แต่ยังคงกลิ่นของ SOAP

ระดับ 2 คือเมื่อคุณใช้คำกริยา HTTP - GET, POST, DELETE เป็นหลัก นี่คือระดับที่ REST เข้ามาในภาพจริงๆ

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

ลิงค์แนะนำสำหรับอ่านเพิ่มเติม:


1

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

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

สำหรับคำถามของคุณ: เอกสารเชิงบรรทัดฐานของเรามีการเปิดเผยทรัพยากรผลกระทบของวิธีการต่างๆที่มีต่อทรัพยากรเหล่านั้นและประเภทสื่อการแสดงที่ใช้และสคีมาและประเภทของทรัพยากรที่ URI ในการแสดงเหล่านั้นชี้ไปที่

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


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

1
ที่จริงฉันเห็นด้วย ฉันเชื่อว่านั่นคือสิ่งที่ฉันพูด อย่างไรก็ตามฉันไม่เห็นเหตุผลที่ดีในการให้เทมเพลต URI นอกวง
คี ธ โกฮัน

0

สมมติ GET /foos/createFormPOST /foosมีการเรียกที่จะได้รับค่าเขตข้อมูลแบบฟอร์มที่จะต้องให้เมื่อเราไปสร้าง ตอนนี้ URL เฉพาะเช่น 1 ที่ใช้ในการสร้าง foos ควรได้รับการกล่าวถึงในคำตอบสำหรับGET /foos/createFormเป็นลิงก์ส่งการดำเนินการตามประพจน์ของ Fielding ใช่ไหม?
แล้วประโยชน์ของการทำแผนที่การกระทำกับคำกริยา Http กับการดำเนินการที่รู้จักกันดีคืออะไรสิ่งที่ "convention over code / config" จะถูกลบล้าง

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