HATEOAS cung cấp những gì cho khả năng khám phá và tách rời bên cạnh khả năng thay đổi cấu trúc URL của bạn ít nhiều một cách tự do?


61

Gần đây tôi đã đọc về Hypermedia với tư cách là Công cụ của Trạng thái Ứng dụng (HATEOAS), ràng buộc được tuyên bố là làm cho API web "thực sự RESTful". Về cơ bản, nó bao gồm các liên kết với mọi phản ứng đối với các chuyển đổi có thể bạn có thể thực hiện từ trạng thái hiện tại.

Hãy để tôi minh họa những gì HATEOAS dựa trên sự hiểu biết của tôi - và vui lòng sửa lại cho tôi nếu tôi bỏ lỡ điều gì đó.

/
    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 được tuyên bố là cung cấp hai lợi ích chính:

  1. Toàn bộ dịch vụ có thể khám phá bắt đầu từ URI gốc, tài liệu không còn cần thiết nữa.

  2. Máy khách được tách rời khỏi máy chủ có thể thay đổi cấu trúc URI một cách tự do. Điều này giúp loại bỏ sự cần thiết phải tạo phiên bản API.

Nhưng theo quan điểm của tôi, một dịch vụ nhiều hơn cấu trúc URI của nó. Để sử dụng nó hiệu quả, bạn cũng cần biết:

  • những tham số truy vấn nào bạn có thể sử dụng và các giá trị có thể có của chúng
  • cấu trúc của JSON / XML / bất kỳ tài liệu nào bạn cần gửi trong các yêu cầu POST / PATCH / etc của bạn
  • cấu trúc của phản hồi được gửi bởi máy chủ
  • các lỗi có thể xảy ra
  • ...

Dựa trên những điều trên, HATEOAS chỉ giải quyết được một phần rất nhỏ các vấn đề về khả năng khám phá và ghép nối. Bạn vẫn cần ghi lại bốn khía cạnh trên và khách hàng vẫn sẽ được kết nối mạnh mẽ với máy chủ vì chúng. Để tránh phá vỡ ứng dụng khách, bạn vẫn cần phải phiên bản API của mình.

Lợi ích duy nhất mà nó cung cấp là bạn có thể thay đổi cấu trúc URL của mình ít nhiều một cách tự do (nhân tiện, điều gì đã xảy ra với nguyên tắc "URI tuyệt vời không thay đổi" ?). Tôi hiểu có đúng không?

Câu trả lời:


46

Tôi nghĩ rằng bản năng của bạn phần lớn là chính xác; những lợi ích được tuyên bố đó thực sự không tuyệt vời lắm, vì đối với bất kỳ ứng dụng web không tầm thường nào, khách hàng sẽ phải quan tâm đến ngữ nghĩa của những gì họ đang làm cũng như cú pháp.

Nhưng điều đó không có nghĩa là bạn không nên làm cho ứng dụng của mình tuân theo các nguyên tắc của HATEOAS!

HATEOAS thực sự có nghĩa là gì? Nó có nghĩa là cấu trúc ứng dụng của bạn sao cho nguyên tắc giống như một trang web và tất cả các hoạt động mà bạn có thể muốn thực hiện có thể được phát hiện mà không cần phải tải xuống một số lược đồ phức tạp. (Các lược đồ WSDL tinh vi có thể bao quát mọi thứ, nhưng vào thời điểm chúng làm, chúng đã vượt quá khả năng của hầu hết mọi lập trình viên để hiểu, hãy để một mình viết! Bạn có thể xem HATEOAS như một phản ứng chống lại sự phức tạp như vậy.)

HATEOAS không chỉ có nghĩa là liên kết phong phú. Điều này có nghĩa là sử dụng các cơ chế lỗi của tiêu chuẩn HTTP để chỉ ra chính xác hơn những gì đã sai; bạn không cần phải trả lời với waaah! không có loại nào và thay vào đó có thể cung cấp một tài liệu mô tả những gì thực sự sai và khách hàng có thể làm gì về nó. Điều đó cũng có nghĩa là hỗ trợ những thứ như yêu cầu TÙY CHỌN (cách tiêu chuẩn cho phép khách hàng tìm ra phương thức HTTP nào họ có thể sử dụng) và đàm phán loại nội dung để định dạng của phản hồi có thể được điều chỉnh theo dạng mà khách hàng có thể xử lý. Nó có nghĩa là đưa vào văn bản giải thích(hoặc, nhiều khả năng, liên kết với nó) để khách hàng có thể tra cứu cách sử dụng hệ thống trong các trường hợp không tầm thường nếu họ không biết; văn bản giải thích có thể đọc được bằng con người hoặc nó có thể đọc được bằng máy (và có thể phức tạp như bạn muốn). Cuối cùng, điều đó có nghĩa là khách hàng không tổng hợp các liên kết (ngoại trừ các tham số truy vấn); khách hàng sẽ chỉ sử dụng một liên kết nếu bạn nói với họ.

Bạn phải suy nghĩ về việc trang web được người dùng duyệt (người có thể đọc JSON hoặc XML thay vì HTML, hơi lạ) với một bộ nhớ tuyệt vời cho các liên kết và kiến ​​thức bách khoa về các tiêu chuẩn HTTP, nhưng nếu không thì không biết gì về làm

Và tất nhiên, bạn có thể sử dụng đàm phán loại nội dung để phục vụ ứng dụng khách HTML (5) / JS sẽ cho phép họ sử dụng ứng dụng của bạn, nếu đó là những gì trình duyệt của họ chuẩn bị chấp nhận. Rốt cuộc, nếu API RESTful của bạn có tốt không, thì đó có phải là tầm thường hay không?


6

Vấn đề là, HATEOAS phải đi kèm với một trụ cột thứ hai xác định API RESTful là gì: loại phương tiện được tiêu chuẩn hóa. Roy bảo vệ mình nói

API REST nên dành hầu hết tất cả nỗ lực mô tả của nó để xác định (các) loại phương tiện được sử dụng để thể hiện tài nguyên ".

Với loại phương tiện được tiêu chuẩn hóa xác định rõ ràng quá trình chuyển đổi và siêu văn bản để trỏ tài nguyên cho nhau, bạn có thể tạo một biểu đồ tài nguyên có thể ở bất kỳ dạng nào mà không phá vỡ bất kỳ máy khách nào. Giống như công việc web, thực sự: bạn có liên kết giữa tài liệu và tài liệu được viết bằng HTML xác định cách theo các liên kết đó. <a href>là GET, <form>là GET hoặc POST (và xác định mẫu url sẽ sử dụng trong trường hợp GET), <link type="text/css">là GET ... vv Đây là cách trình duyệt có thể điều hướng trang HTML có cấu trúc tùy ý và Web.

Tất cả những điểm bạn đã làm

  • những tham số truy vấn nào bạn có thể sử dụng và các giá trị có thể có của chúng
  • cấu trúc của JSON / XML / bất kỳ tài liệu nào bạn cần gửi trong các yêu cầu POST / PATCH / etc của bạn
  • cấu trúc của phản hồi được gửi bởi máy chủ
  • các lỗi có thể xảy ra

Là những điểm nên được nhấn mạnh bởi định nghĩa của loại phương tiện tiêu chuẩn hóa của bạn . Tất nhiên, điều này khó hơn nhiều và không phải là điều mà hầu hết mọi người nghĩ đến khi họ định nghĩa API "REST". Bạn không thể đưa bạn thực thể kinh doanh và chuyển các thuộc tính của chúng vào tài liệu JSON để có API RESTful.

Tất nhiên, những gì đã xảy ra là REST đã bị pha loãng bằng cách nào đó có nghĩa là "sử dụng HTTP thay vì điều phức tạp SOAPy". Chỉ sử dụng HTTP và HyperText là không đủ để trở thành RESTful, đây là điều mà hầu hết mọi người đều hiểu sai.

Không phải điều này là cần thiết một điều xấu: REST hy sinh hiệu suất và dễ dàng phát triển để đổi lấy khả năng duy trì và phát triển lâu dài hơn. Nó được thực hiện để tích hợp ứng dụng lớn. Một API web nhỏ với cấu trúc JSON được mã hóa cứng có thể là thứ bạn cần. Đừng gọi nó là REST, API web đặc biệt, không có gì khác. Và điều đó không có nghĩa là nó tệ, nó chỉ có nghĩa là nó không cố gắng tuân theo sự ràng buộc của REST.

đọc thêm

Hy vọng điều này sẽ giúp làm rõ một chút :)


2

Có một số định dạng Hypermedia nỗ lực cung cấp phản hồi phong phú hơn bao gồm nhiều thông tin hơn về loại yêu cầu gửi và không có gì ngăn bạn làm phong phú thêm phản hồi với nhiều thông tin hơn.

Dưới đây là một ví dụ về tài liệu Siren :

{
  "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" }
  ]
}

Như bạn có thể thấy, thông tin về cách gọi liên quan actionsđược cung cấp trong tin nhắn, và sau đó bằng cách diễn giải thông tin này, khách hàng trở nên chống lại sự thay đổi.

Nó trở nên đặc biệt mạnh mẽ nếu rels là các URI có thể tra cứu, thay vì từ vựng cố định.


0

Bạn đã đọc "tài liệu không còn cần thiết" ở đâu cho các dịch vụ HATEAOS? Như bạn nói, bạn vẫn cần ghi lại ngữ nghĩa của các liên kết. Tuy nhiên, với HATEOAS, bạn không cần phải ghi lại và do đó giữ mãi mãi, cấu trúc của hầu hết các URI.

HATEOAS cho phép người triển khai dịch vụ sửa đổi và mở rộng quy mô triển khai một cách đáng kể và hiệu quả mà không cần thay đổi một bộ URI nhỏ mà khách hàng phụ thuộc. Sẽ dễ dàng hơn để giữ một số lượng nhỏ điểm nhập không thay đổi so với một tập hợp lớn. Do đó, việc giảm số lượng điểm vào công khai cho dịch vụ và cung cấp liên kết động đến các tài nguyên phụ (HATEOAS) thực sự hỗ trợ "URI tuyệt vời không thay đổi" tốt hơn các dịch vụ không phải của HATEOAS.


Một nơi mà người ta có thể đọc rằng "tài liệu không còn cần thiết nữa" là luận án của Roy Fielding, người đã đặt ra thuật ngữ này.
meriton - đình công

1
Tôi vừa tìm kiếm luận văn của Fielding để sử dụng "tài liệu" và thấy không có gì giống với tuyên bố "tài liệu không còn cần thiết". Bạn có thể vui lòng cho biết nơi nào trong luận án của Fielding bạn đã tìm thấy khiếu nại này không?
Jonathan Giddy

0

(HATEOAS), ràng buộc được tuyên bố là làm cho API web "thực sự RESTful"

Điều duy nhất làm cho nó trở thành một API REST thực sự là đáp ứng tất cả các ràng buộc, không chỉ một ràng buộc.

Nhưng theo quan điểm của tôi, một dịch vụ nhiều hơn cấu trúc URI của nó. Để sử dụng nó hiệu quả, bạn cũng cần biết: ...

Đó là lý do tại sao chúng ta cần các ràng buộc khác, thông điệp tự mô tả, v.v ...

Để tránh phá vỡ ứng dụng khách, bạn vẫn cần phải phiên bản API của mình.

Cho dù bạn cố gắng thế nào, bạn sẽ cần phải phiên bản API của mình. Trong ứng dụng khách REST, bạn vẫn cần biết cách truy cập trang mà bạn muốn thực hiện công việc, liên kết nào để theo dõi và thuộc tính nào bạn cần thu thập dựa trên từ vựng RDF mô tả thông báo. Nếu bạn cần thay thế hoặc xóa một cái gì đó khỏi vocab đó, thì nó có thể sẽ phá vỡ tất cả các khách hàng của bạn và bạn sẽ cần một phiên bản mới. Vì vậy, tôi nghĩ REST không phải là thứ bạn nên xuất bản sớm (và tìm ra mô hình trong khi bạn liên tục thay đổi API), nếu không bạn sẽ có nhiều phiên bản. Bạn cần một mô hình miền ổn định trước tiên bạn có thể xây dựng trên ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.