HATEOAS เสนออะไรให้ค้นพบและแยกส่วนนอกเหนือจากความสามารถในการเปลี่ยนโครงสร้าง URL ของคุณอย่างอิสระมากขึ้นหรือน้อยลง


61

เมื่อเร็ว ๆ นี้ฉันได้อ่านเกี่ยวกับ Hypermedia ว่าเป็น Engine of Application State (HATEOAS) ซึ่งเป็นข้อ จำกัด ที่อ้างว่าทำให้ API ของเว็บ "สงบ" อย่างแท้จริง โดยทั่วไปแล้วจะรวมถึงลิงก์ที่มีการตอบสนองต่อการเปลี่ยนแปลงที่เป็นไปได้ทั้งหมดที่คุณสามารถทำได้จากสถานะปัจจุบัน

ให้ฉันอธิบายสิ่งที่ HATEOAS ตั้งอยู่บนความเข้าใจของฉัน - และโปรดแก้ไขให้ถูกต้องหากฉันพลาดอะไรไป

/
    GET: {
        "_links": {
            "child": [
                { "href": "http://myapi.com/articles", "title": "articles" }
            ]
        }
    }

/articles?contains=HATEOAS
    GET: {
        "_items": [
            { "uri": "http://myapi.com/articles/0", "title": "Why Should I Care About HATEOAS?" },
            { "uri": "http://myapi.com/articles/1", "title": "HATEOAS: Problem or Solution?" }
        ],
        "_links": {
            "self": { "href": "http://myapi.com/articles", "title": "articles" },
            "parent": { "href": "http://myapi.com/", "title": "home" }
        }
    }

    POST: {
        "title": "A New Article",
        "body": "Article body",
        "tags": [ "tag1", "tag2" ]
    }

/articles/0
    GET: {
        "title": "Why Should I Care About HATEOAS?",
        "body": "Blah blah blah"
        "tags": [ "REST", "HATEOAS" ],
        "_links": {
            "self": { "href": "http://myapi.com/articles/0", "title": "article" },
            "parent": { "href": "http://myapi.com/articles", "title": "articles" }
        }
    }

HATEOAS ได้รับการกล่าวอ้างว่าให้ประโยชน์ที่สำคัญสองประการ:

  1. บริการทั้งหมดสามารถค้นพบได้ในรูปแบบเริ่มต้นของ URI รูทไม่จำเป็นต้องใช้เอกสารอีกต่อไป

  2. ไคลเอ็นต์ถูกแยกออกจากเซิร์ฟเวอร์ซึ่งสามารถเปลี่ยนโครงสร้าง URI ได้อย่างอิสระ สิ่งนี้ไม่จำเป็นสำหรับการกำหนดเวอร์ชัน API

แต่ในมุมมองของฉันการบริการเป็นมากกว่าโครงสร้างของ URI หากต้องการใช้อย่างมีประสิทธิภาพคุณต้องรู้:

  • พารามิเตอร์การสืบค้นใดที่คุณสามารถใช้และค่าที่เป็นไปได้
  • โครงสร้างของ JSON / XML / เอกสารอะไรก็ตามที่คุณต้องการส่งในคำขอ POST / PATCH / etc ของคุณ
  • โครงสร้างของการตอบสนองที่ส่งโดยเซิร์ฟเวอร์
  • ข้อผิดพลาดที่เป็นไปได้ที่อาจเกิดขึ้น
  • ...

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

ประโยชน์เพียงอย่างเดียวที่มีให้คือคุณสามารถเปลี่ยนโครงสร้าง URL ของคุณได้อย่างอิสระมากขึ้น (โดยวิธีการเกิดอะไรขึ้นกับหลักการ"Cool URIs ที่ไม่เปลี่ยนแปลง" ?) ความเข้าใจของฉันถูกต้องหรือไม่

คำตอบ:


46

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

แต่นั่นไม่ได้หมายความว่าคุณไม่ควรทำให้ใบสมัครของคุณเป็นไปตามหลักการของ HATEOAS!

HATEOAS หมายถึงอะไรจริง ๆ ? มันหมายถึงการจัดโครงสร้างแอปพลิเคชันของคุณเพื่อให้เป็นไปตามหลักการเหมือนกับเว็บไซต์และการดำเนินการทั้งหมดที่คุณอาจต้องการทำสามารถค้นพบได้โดยไม่ต้องดาวน์โหลดสคีมาที่ซับซ้อน (schema ที่มีความซับซ้อนของ WSDL สามารถครอบคลุมทุกอย่าง แต่ตามเวลาที่ทำพวกเขาได้เกินขีดความสามารถของโปรแกรมเมอร์ทุกคนที่จะเข้าใจเคยให้เขียนคนเดียว! คุณสามารถดู HATEOAS เป็นปฏิกิริยาต่อความซับซ้อนดังกล่าว

HATEOAS ไม่ได้หมายถึงลิงก์ที่หลากหลายเท่านั้น หมายความว่าการใช้กลไกข้อผิดพลาดมาตรฐาน HTTPเพื่อระบุสิ่งที่ผิดพลาด คุณไม่จำเป็นต้องตอบกลับด้วย“ waaah! ไม่” และสามารถให้เอกสารอธิบายสิ่งที่ผิดจริงและลูกค้าอาจทำอะไรเกี่ยวกับมัน นอกจากนี้ยังหมายถึงการสนับสนุนสิ่งต่าง ๆ เช่นการร้องขอ OPTIONS (วิธีมาตรฐานในการอนุญาตให้ลูกค้าค้นหาวิธี HTTP ที่พวกเขาสามารถใช้) และการเจรจาประเภทเนื้อหาเพื่อให้สามารถปรับรูปแบบการตอบสนองให้เป็นรูปแบบที่ลูกค้าสามารถจัดการได้ มันหมายถึงการใส่ข้อความอธิบาย(หรือมีโอกาสมากขึ้นที่ลิงค์ไปยังมัน) เพื่อให้ลูกค้าสามารถค้นหาวิธีการใช้ระบบในกรณีที่ไม่สำคัญหากพวกเขาไม่รู้ ข้อความอธิบายอาจเป็นมนุษย์สามารถอ่านได้หรืออาจเป็นเครื่องที่อ่านได้ (และอาจซับซ้อนตามที่คุณต้องการ) ในที่สุดก็หมายความว่าลูกค้าไม่ได้ทำการเชื่อมโยง (ยกเว้นพารามิเตอร์การสืบค้น); ลูกค้าจะใช้ลิงค์เมื่อคุณบอกให้พวกเขาทราบเท่านั้น

คุณต้องนึกถึงการมีไซต์ที่เรียกดูโดยผู้ใช้ (ผู้ที่สามารถอ่าน JSON หรือ XML แทนที่จะเป็น HTML แปลก ๆ นิดหน่อย) ด้วยหน่วยความจำที่ยอดเยี่ยมสำหรับลิงค์และสารานุกรมความรู้เกี่ยวกับมาตรฐาน HTTP แต่ไม่มีความรู้เกี่ยวกับสิ่งที่จะ ทำ.

และแน่นอนคุณสามารถใช้การเจรจาประเภทเนื้อหาเพื่อให้บริการลูกค้า HTML (5) / JS ที่จะให้พวกเขาใช้แอปพลิเคชันของคุณหากนั่นคือสิ่งที่เบราว์เซอร์ของพวกเขาพร้อมที่จะยอมรับ ท้ายที่สุดแล้วถ้า RESTful API ของคุณนั้นดีอะไรควรเป็นเรื่องเล็กน้อยที่จะนำไปใช้ประโยชน์


6

สิ่งคือ HATEOAS จะต้องมาพร้อมกับเสาหลักที่สองที่กำหนดว่า RESTful API คืออะไร: ประเภทสื่อมาตรฐาน รอยฟีลดิงพูดกับตัวเอง

REST API ควรใช้ความพยายามเกือบทั้งหมดในการกำหนดประเภทสื่อที่ใช้สำหรับแสดงทรัพยากร "

ด้วยประเภทสื่อมาตรฐานที่กำหนดช่วงการเปลี่ยนภาพอย่างชัดเจนและไฮเปอร์เท็กซ์เพื่อกำหนดทรัพยากรให้กันคุณสามารถสร้างกราฟทรัพยากรที่สามารถใช้รูปแบบใดก็ได้โดยไม่ทำให้ลูกค้าแตก เช่นเดียวกับการทำงานบนเว็บจริงๆ: คุณมีลิงก์ระหว่างเอกสารและเอกสารเขียนด้วย HTML ที่กำหนดวิธีการติดตามลิงก์เหล่านั้น <a href>เป็น GET <form>คือ GET หรือ POST (และกำหนดแม่แบบ URL ที่จะใช้ในกรณีของ GET) <link type="text/css">คือ GET ... เป็นต้นนี่คือวิธีที่เบราว์เซอร์สามารถนำทางหน้า HTML และเว็บที่มีโครงสร้างตามอำเภอใจได้

ทุกจุดที่คุณทำ

  • พารามิเตอร์การสืบค้นใดที่คุณสามารถใช้และค่าที่เป็นไปได้
  • โครงสร้างของ JSON / XML / เอกสารอะไรก็ตามที่คุณต้องการส่งในคำขอ POST / PATCH / etc ของคุณ
  • โครงสร้างของการตอบสนองที่ส่งโดยเซิร์ฟเวอร์
  • ข้อผิดพลาดที่เป็นไปได้ที่อาจเกิดขึ้น

เป็นจุดที่ควรจะ adressed โดยความหมายของคุณชนิดของสื่อที่ได้มาตรฐาน แน่นอนว่ามันยากกว่าและไม่ใช่สิ่งที่คนส่วนใหญ่คิดเมื่อพวกเขากำหนด API "REST" คุณไม่สามารถนำเอนทิตีธุรกิจของคุณและผลักคุณลักษณะของพวกเขาไปยังเอกสาร JSON เพื่อให้ได้ RESTful API

แน่นอนสิ่งที่เกิดขึ้นคือ REST ได้รับการปรับลดอย่างใดเพื่อหมายถึง "ใช้ HTTP แทน SOAPy thingy ที่ซับซ้อน" เพียงแค่ใช้ HTTP และ HyperText ก็ไม่เพียงพอที่จะให้ความสงบนี่คือสิ่งที่คนส่วนใหญ่เข้าใจผิด

ไม่ใช่ว่าสิ่งนี้เป็นสิ่งที่ไม่ดี: REST เสียสละประสิทธิภาพและความสะดวกในการพัฒนาเพื่อแลกกับการบำรุงรักษาในระยะยาวและวิวัฒนาการ มันถูกสร้างขึ้นมาสำหรับการรวมแอพพลิเคชั่นขนาดใหญ่ API เว็บขนาดเล็กที่มีโครงสร้าง JSON แบบกำหนดรหัสตายตัวอาจเป็นสิ่งที่คุณต้องการ อย่าเรียกว่า REST ซึ่งเป็น ad-hoc web API ไม่มีอะไรเพิ่มเติม และนั่นไม่ได้หมายความว่ามันดูด แต่ก็หมายความว่ามันไม่ได้พยายามทำตามข้อ จำกัด ของ REST

อ่านเพิ่มเติม

หวังว่าความช่วยเหลือนี้จะช่วยให้ชัดเจนขึ้น :)


2

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

นี่คือตัวอย่างของเอกสารไซเรน :

{
  "class": [ "order" ],
  "properties": { 
      "orderNumber": 42, 
      "itemCount": 3,
      "status": "pending"
  },
  "entities": [
    {
      "class": [ "info", "customer" ],
      "rel": [ "http://x.io/rels/customer" ], 
      "properties": { 
        "customerId": "pj123",
        "name": "Peter Joseph"
      },
      "links": [
        { "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
      ]
    }
  ],
  "actions": [
    {
      "name": "add-item",
      "title": "Add Item",
      "method": "POST",
      "href": "http://api.x.io/orders/42/items",
      "type": "application/x-www-form-urlencoded",
      "fields": [
        { "name": "orderNumber", "type": "hidden", "value": "42" },
        { "name": "productCode", "type": "text" },
        { "name": "quantity", "type": "number" }
      ]
    }
  ],
  "links": [
    { "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
    { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
    { "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
  ]
}

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

มันจะมีประสิทธิภาพโดยเฉพาะอย่างยิ่งถ้าrels เป็น URIs ซึ่งสามารถค้นหาได้มากกว่าจากคำศัพท์ที่ตายตัว


0

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

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


ที่เดียวที่สามารถอ่านได้ว่า "เอกสารไม่จำเป็นอีกต่อไป" คือวิทยานิพนธ์ของ Roy Fielding ซึ่งเป็นคนบัญญัติศัพท์
meriton - เมื่อ

1
ฉันเพิ่งค้นหาวิทยานิพนธ์ของ Fieldingสำหรับการใช้ "เอกสาร" และไม่พบสิ่งใดที่คล้ายกับคำแถลง "เอกสารไม่จำเป็นอีกต่อไป" คุณช่วยระบุว่าในวิทยานิพนธ์ของ Fielding คุณพบข้อเรียกร้องนี้ได้ที่ไหน?
Jonathan Giddy

0

(HATEOAS) ข้อ จำกัด ที่อ้างว่าทำให้ API ของเว็บ "สงบ" อย่างแท้จริง

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

แต่ในมุมมองของฉันการบริการเป็นมากกว่าโครงสร้างของ URI หากต้องการใช้อย่างมีประสิทธิภาพคุณต้องรู้: ...

นั่นเป็นเหตุผลที่เราต้องการข้อ จำกัด อื่น ๆ ข้อความอธิบายตนเอง ฯลฯ ...

เพื่อหลีกเลี่ยงการทำให้ลูกค้าแตกคุณยังคงต้องใช้ API ของคุณ

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

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