Điểm nào với HATEOAS ở phía khách hàng?


35

Như tôi hiện đang hiểu, HATEOAS về cơ bản là tất cả về việc gửi cùng với mỗi liên kết phản hồi với thông tin về những việc cần làm tiếp theo. Một ví dụ đơn giản có thể dễ dàng tìm thấy trên internet: một hệ thống ngân hàng cùng với tài nguyên tài khoản. Ví dụ cho thấy phản hồi này sau khi yêu cầu NHẬN tài nguyên tài khoản

GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK 
<?xml version="1.0"?> 
<account> 
    <account_number>12345</account_number> 
    <balance currency="usd">100.00</balance> 
    <link rel="deposit" href="/account/12345/deposit" /> 
    <link rel="withdraw" href="/account/12345/withdraw" /> 
    <link rel="transfer" href="/account/12345/transfer" /> 
    <link rel="close" href="/account/12345/close" /> 
</account>

Cùng với dữ liệu có các liên kết cho biết những gì có thể được thực hiện tiếp theo. Nếu số dư là âm chúng ta có

GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK 
<?xml version="1.0"?> 
<account> 
    <account_number>12345</account_number> 
    <balance currency="usd">-25.00</balance> 
    <link rel="deposit" href="/account/12345/deposit" /> 
</account>

Vì vậy, chúng tôi chỉ có thể gửi tiền. Điều đó hoàn toàn tốt, nếu chúng ta đang sử dụng Fiddler hoặc thực hiện các yêu cầu với trình duyệt, chúng ta có thể dễ dàng thấy những gì có thể được thực hiện. Loại thông tin này hữu ích sau đó để chúng tôi khám phá các khả năng của API và máy chủ được tách rời khỏi máy khách.

Tuy nhiên, vấn đề là khi chúng tôi xây dựng một ứng dụng khách, như một SPA với Javascript, hoặc một ứng dụng Android hoặc nhiều thứ khác, tôi không thể thấy HATEOAS tiếp tục liên quan như thế nào. Ý tôi là như sau: khi tôi mã hóa SPA bằng javascript, tôi phải biết những gì có thể được thực hiện trong API để viết mã.

Vì vậy, tôi cần biết các tài nguyên, các phương thức được hỗ trợ, những gì họ mong muốn nhận được và những gì họ trả lại để viết các cuộc gọi ajax đến máy chủ và thậm chí để xây dựng giao diện người dùng. Khi tôi xây dựng giao diện người dùng, tôi phải biết rằng sau khi yêu cầu tài khoản, người ta có thể gửi tiền vào tài khoản đó, hoặc tôi sẽ không thể cung cấp tùy chọn này trên giao diện người dùng. Ngoài ra, tôi sẽ cần biết URI để thực hiện gửi tiền để xây dựng cuộc gọi ajax.

Ý tôi là, khi chúng tôi yêu cầu API, các liên kết cho phép chúng tôi khám phá và sử dụng API tốt hơn, nhưng khi chúng tôi xây dựng một ứng dụng khách, ứng dụng chúng tôi đang xây dựng sẽ không chỉ nhìn vào các liên kết và sau đó tự hiển thị UI chính xác và thực hiện các cuộc gọi ajax đúng.

Vậy, HATEOAS quan trọng như thế nào đối với khách hàng? Tại sao chúng ta bận tâm với HATEOAS?


1
Bạn nói đúng, nhưng đó không phải là vấn đề. HATEOAS giúp bạn không phải xây dựng các URI cho các liên kết trong trang trên máy khách.
James McLeod

Câu trả lời:


24

ứng dụng chúng tôi đang xây dựng sẽ không chỉ đơn giản là nhìn vào các liên kết và sau đó tự nó hiển thị giao diện người dùng chính xác và thực hiện các cuộc gọi ajax đúng

Trên thực tế, đây chính xác là những gì HATEOAS sẽ cung cấp cho UI. Không phải những gì có thể, nhưng khi nó có thể. Một HATEOAS chính thức như HAL , như câu hỏi nêu ra, đưa ra các liên kết chỉ ra những gì có thể. Nhưng khi các liên kết đó xuất hiện phụ thuộc vào trạng thái của ứng dụng. Vì vậy, các liên kết có thể thay đổi trên tài nguyên theo thời gian (dựa trên các hành động đã được thực hiện).

Điều này cho phép chúng ta xây dựng một giao diện người dùng có chứa tất cả các khả năng quốc gia, nhưng không được quan tâm khi những quốc gia trở thành hoạt động. Ví dụ: sự hiện diện của rel="deposit"giao diện người dùng có thể trực tiếp báo cho UI khi nào có thể hiển thị make depositbiểu mẫu. Sau đó cho phép người dùng nhập một giá trị và gửi bằng liên kết.


2
Vì vậy, khi xây dựng giao diện người dùng, chúng ta vẫn cần biết mọi thứ mà API cung cấp, và sau đó nhìn vào các liên kết đó, chúng ta có thể biết trạng thái thông tin trên máy chủ không? Vì vậy, ví dụ, UI biết có thể gửi, rút, chuyển hoặc đóng (biết các rels có thể), sau đó nó kiểm tra những gì đã quay lại để xem trạng thái?
dùng1620696

1
Vâng, nó có thể. Một lần nữa, nó phụ thuộc vào mức độ năng động mà bạn muốn thực hiện. Như những người khác đã đề cập, khả năng thay đổi liên kết trên máy chủ (và không phá vỡ máy khách) là một lợi thế khác. Và điều này trở nên rất thú vị khi API của bạn có ứng dụng khách iPhone, Android, Windows Phone, Web di động và Web mà tất cả đều sử dụng nó (không đề cập đến nếu API của bạn được xuất bản cho người khác để xây dựng ứng dụng khách).
Davin Tryon

@ user1620696 Dù sao thì bạn cũng nên biết tất cả những điều này thông qua cả máy khách và máy chủ dưới dạng nội dung nếu resoure. Loại nội dung nhiều hơn nhiều so với xml hoặc Json câm. Bạn nên có một số loại nội dung "tiền gửi ngân hàng" mà khách hàng hiểu cách làm việc với
Cormac Mulhall

1
@Nik hãy xem HAL để biết ví dụ về cách các liên kết được cung cấp trong phản hồi.
Davin Tryon

1
vâng, bạn vẫn có mối quan tâm tương thích ngược. Điều này có thể được giải quyết bằng cách bao gồm một tiêu đề phiên bản hoặc phiên bản trong url. Nhưng, tôi sẽ nói bạn đang hiểu chính xác.
Davin Tryon

3

Như tôi hiện đang hiểu, HATEOAS về cơ bản là tất cả về việc gửi cùng với mỗi liên kết phản hồi với thông tin về những việc cần làm tiếp theo

HATEOAS không chỉ là liên kết. Nó là "siêu phương tiện" như là công cụ của trạng thái ứng dụng.

Những gì bị bỏ lỡ trong mô tả của bạn là loại nội dung, định nghĩa chính thức của siêu phương tiện được truyền giữa máy khách và máy chủ.

HTML là một ví dụ về siêu phương tiện và là một ví dụ về lý do tại sao HATEOS hoạt động. Bản thân trang HTML là công cụ cho phép khách hàng (tức là người dùng) di chuyển qua trang web. Một trình duyệt chỉ có khả năng hiển thị HTML hiện diện cho người dùng một trang web có thể điều hướng hoàn toàn. Nó không chỉ đơn giản là nó chuyển các liên kết đến các trang khác mà nó chuyển chúng theo một cách có ý nghĩa mang lại bối cảnh cho các liên kết và theo cách thức cho phép trình duyệt xây dựng một trang web có thể điều hướng.

Và quan trọng nhất là trình duyệt có thể làm điều này với sự hiểu biết trước về trang web. Trình duyệt chỉ biết HTTP và HTML. Dựa trên sự hiểu biết đơn giản đó, nó có thể trình bày Thời báo New York cho người dùng để điều hướng qua.

Điều này giữ ngay cả khi "người dùng" là một chương trình máy tính khác. Các siêu phương tiện nên xác định bối cảnh của điều hướng.


1
Điều này có nghĩa là bạn phải xây dựng một ứng dụng khách phức tạp (và dễ bị lỗi) như một trình duyệt? Tính linh hoạt thường đi kèm với sự phức tạp như một chi phí ...
Andres F.

@AresresF. điều đó không có nghĩa là bạn phải hoặc nên làm như vậy, nó chỉ cung cấp cho bạn tùy chọn để thực hiện một cách linh hoạt nếu bạn muốn hoặc cần nó.
Peteris

2
@nik Chắc chắn rồi. Ra khỏi đầu tôi tưởng tượng rằng bạn có một dịch vụ cung cấp thông tin tổ tiên thông qua api yên tĩnh. Bạn có loại nội dung xác định định dạng của tài nguyên 'Người' có nhiều thông tin khác nhau về họ nhưng cũng xác định mối quan hệ trông như thế nào, nói 'anh trai' hoặc 'chị' hoặc 'mẹ', v.v ... Bởi vì đây đơn giản là những mối quan hệ đó có một URI cho tài nguyên Người khác. Một khách hàng khá đơn giản sử dụng các động từ HTTP và hiểu loại nội dung 'Người' này có thể điều hướng qua API này. Nói rằng bạn muốn tìm tất cả con cháu trực tiếp của một người cụ thể.
Cormac Mulhall

2
@nik Khách hàng này cần hiểu đơn giản là loại nội dung của tài nguyên mà nó đã truy cập và các động từ HTTP (GET, PUT, DELETE, v.v.) và bạn có thể điều hướng thông qua tài nguyên tìm nạp và cập nhật API này. Và, quan trọng hơn, bất kỳ khách hàng nào hiểu loại nội dung đều có thể nhảy, thông qua URI, đến một máy chủ khác hoàn toàn và tiếp tục như hiện tại. Họ không quan tâm máy chủ họ đang nói chuyện với cái gì, họ chỉ quan tâm đến loại nội dung của tài nguyên, họ có hiểu hay không.
Cormac Mulhall

1
@Nik Vì vậy, trong tình huống như vậy, bạn có một máy chủ hiểu loại nội dung gốc (người Person v1) và loại nội dung mới (Người v2). Khách hàng chỉ hiểu Người v1. Máy khách báo cho máy chủ biết loại nội dung mà nó hiểu thông qua tiêu đề Chấp nhận trong HTTP. Sử dụng đàm phán nội dung, máy chủ sẽ xác định xem nó có gửi những gì khách hàng hỗ trợ hay không, trong trường hợp đó, nó sẽ trả về tài nguyên bằng cách sử dụng kiểu nội dung Person v1. Bây giờ bạn có thể chỉ muốn ngừng hỗ trợ loại nội dung cũ này và có thể gửi cho khách hàng một lỗi 406. Nó là tốt hơn để cố gắng và hỗ trợ càng nhiều càng tốt.
Cormac Mulhall

2

Bạn không phải xây dựng một giao diện được tạo động. Mặc dù nó có thể tốt nhưng nó không bắt buộc. Nếu bạn không thể xây dựng một giao diện động, chỉ cần sử dụng các liên kết và bạn đã hoàn thành. Nhược điểm là bạn lại khó liên kết với phụ trợ và sẽ gặp sự cố nếu có gì đó thay đổi.

Sử dụng bố cục động có thể khá đơn giản btw:

links.forEach(function(link) {

  switch(link.rel) {

    case 'deposit':
      showDepositButton();
      break;

    case 'withdraw':
      loadWithdrawForm(link.href);
      showWithdrawButton();
      break;
  }

});

Nó tiết kiệm cho bạn trong mã khách hàng của bạn như:

if (balance <= 0 && negativeBalanceAllowed === false) {
  showWithdrawButton();
}

Bạn có thể thực hiện một vị trí tiêu cực được phép (ví dụ bằng cách vay tiền) mà không thay đổi khách hàng của bạn.


Như một ví dụ mạnh hơn một chút, ngân hàng có thể đưa ra các giới hạn thấu chi thay đổi trên tài khoản của họ, mà không phải thông báo cho phía khách hàng về giới hạn đối với mỗi tài khoản.
Bart van Ingen Schenau 9/2/2015

Chính xác, bạn có thể đưa ra quyết định giới hạn số dư phức tạp như bạn muốn và vẫn không phải thực hiện thay đổi cho khách hàng. Nếu bạn thực hiện điều này hơn nữa với các phần REST như kiểu nội dung, bạn có thể hiển thị các chế độ xem khác nhau. Ví dụ, một tài khoản trông khác với một giao dịch. Cũng thú vị là mã theo yêu cầu (mặc dù không được thực hiện nhiều). Điều đó có thể được sử dụng ví dụ cho một người ước tính vay. Nó có thể cung cấp cho giao diện một chức năng tính toán đơn giản để khách hàng chỉ cần thực hiện các đầu vào để tính toán. Nó sẽ được cập nhật từ back-end.
Luc Franken

2
Nhưng thông thường, khách hàng cần biết TẠI SAO không thể rút tiền, vì vậy chúng tôi vẫn cần gửi ENUM hoặc Chuỗi trong trường riêng cho khách hàng reason. Và nếu chúng ta vẫn cần điều này, tại sao không đơn giản gửi cho anh ta một trường boolean khác canWithdrawthay vì liên kết đến hành động? Một lợi thế khác là khả năng thay đổi URL của một hành động mà không cần chạm vào máy khách. Nhưng .. lý do nào để thay đổi URL? Trong hầu hết các trường hợp, nó cũng có một số thay đổi về ngữ nghĩa hoặc tham số hoặc hình dạng yêu cầu / phản hồi, v.v ... Vì vậy, dù sao chúng ta cũng cần thay đổi máy khách. Vì vậy, tôi vẫn không hiểu được - quan điểm của HATEOAS là gì.
Ruslan Stelmachenko
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.