Co oferuje HATEOAS w zakresie wykrywalności i oddzielania, oprócz możliwości mniej lub bardziej swobodnej zmiany struktury adresu URL?

61

Ostatnio czytałem o Hypermedia jako silniku stanu aplikacji (HATEOAS), ograniczeniu, które, jak się twierdzi, sprawia, że ​​interfejs API sieci Web jest „naprawdę RESTful”. Sprowadza się to zasadniczo do uwzględnienia łączy z każdą odpowiedzią na możliwe przejścia, które możesz wykonać z bieżącego stanu.

Pozwól mi zilustrować, co HATEOAS opiera się na moim zrozumieniu - i proszę popraw mnie, jeśli coś przeoczyłem.

/
    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 ma zapewniać dwie główne korzyści:

  1. Cała usługa jest wykrywalna, począwszy od głównego identyfikatora URI, dokumentacja nie jest już potrzebna.

  2. Klient jest oddzielony od serwera, który może teraz dowolnie zmieniać strukturę URI. Eliminuje to potrzebę wersjonowania interfejsu API.

Ale moim zdaniem usługa to znacznie więcej niż jej struktura URI. Aby skutecznie go używać, musisz także wiedzieć:

  • jakich parametrów zapytania można użyć i ich możliwych wartości
  • struktura JSON / XML / dowolne dokumenty, które musisz wysłać w swoich żądaniach POST / PATCH / etc
  • struktura odpowiedzi wysłanej przez serwer
  • możliwe błędy, które mogą wystąpić
  • ...

W oparciu o powyższe, HATEOAS rozwiązuje tylko niewielką część problemów związanych z wykrywalnością i sprzężeniem. Nadal musisz udokumentować powyższe cztery aspekty, a dzięki temu klienci nadal będą silnie powiązani z serwerem. Aby uniknąć łamania klientów, nadal musisz zaktualizować swój interfejs API.

Jedyną korzyścią, jaką zapewnia, jest to, że możesz mniej lub bardziej swobodnie zmieniać strukturę adresów URL (tak przy okazji, co stało się z zasadą „Fajne URI się nie zmieniają” ?). Czy moje rozumowanie jest prawidłowe?

Botond Balázs
źródło

Odpowiedzi:

46

Myślę, że twoje instynkty są w dużej mierze prawidłowe; te deklarowane korzyści naprawdę nie są aż tak świetne, ponieważ dla każdej nietrywialnej aplikacji internetowej klienci będą musieli dbać o semantykę tego, co robią, a także składnię.

Ale to nie znaczy, że nie powinieneś składać aplikacji zgodnie z zasadami HATEOAS!

Co tak naprawdę znaczy HATEOAS ? Oznacza to taką strukturę aplikacji , aby była ona zasadniczo jak strona internetowa i aby wszystkie operacje, które możesz chcieć wykonać, można wykryć bez konieczności pobierania skomplikowanego schematu. (Wyrafinowane schematy WSDL mogą obejmować wszystko, ale do tego czasu przekroczyły zdolność praktycznie każdego programisty do zrozumienia, a co dopiero pisania! Możesz zobaczyć HATEOAS jako reakcję na taką złożoność.)

HATEOAS to nie tylko bogate linki. Oznacza to wykorzystanie mechanizmów błędów standardu HTTP w celu dokładniejszego wskazania, co poszło nie tak; nie musisz po prostu odpowiadać „waaah! nie ”i zamiast tego może dostarczyć dokument opisujący, co faktycznie było nie tak i co klient może z tym zrobić. Oznacza to także obsługę takich elementów, jak żądania OPCJE (standardowy sposób pozwalający klientom dowiedzieć się, jakich metod HTTP mogą użyć) oraz negocjowanie typów treści, aby format odpowiedzi można było dostosować do formularza obsługiwanego przez klientów. Oznacza wstawienie tekstu wyjaśniającego(lub, bardziej prawdopodobne, linki do niego), aby klienci mogli sprawdzić, jak korzystać z systemu w nietrywialnych przypadkach, jeśli nie wiedzą; tekst objaśniający może być czytelny dla człowieka lub może być do odczytu maszynowego (i może być tak złożony, jak chcesz). Wreszcie oznacza to, że klienci nie syntezują łączy (z wyjątkiem parametrów zapytania); klienci będą używać linku tylko wtedy, gdy im o tym powiesz.

Musisz pomyśleć o tym, aby strona była przeglądana przez użytkownika (który może czytać JSON lub XML zamiast HTML, więc to trochę dziwne) z wielką pamięcią dla linków i encyklopedyczną znajomością standardów HTTP, ale poza tym brak wiedzy o tym, co zrobić zrobić.

I oczywiście możesz użyć negocjacji typu zawartości, aby obsłużyć klienta HTML (5) / JS, który pozwoli im korzystać z Twojej aplikacji, jeśli taka przeglądarka jest gotowa zaakceptować. W końcu, jeśli Twój interfejs API RESTful jest jakiś dobry, to powinno być „trywialne”, aby go wdrożyć?

Donal Fellows
źródło
6

Chodzi o to, że HATEOAS musi mieć drugi filar, który określa, czym jest RESTful API: znormalizowany typ nośnika. - powiedział Roy

Interfejs API REST powinien poświęcić prawie cały swój wysiłek opisowy na zdefiniowanie typów mediów używanych do reprezentowania zasobów ".

Dzięki znormalizowanemu typowi nośnika, który wyraźnie definiuje przejście, i hipertekstowi, aby wskazywać na siebie zasób, możesz utworzyć wykres zasobów, który może przybierać dowolną formę bez przerywania jakiegokolwiek klienta. Tak jak praca w sieci, naprawdę: masz link między dokumentem, a dokument jest napisany w HTML, który definiuje sposób korzystania z tych łączy. <a href>jest GET, <form>jest GET lub POST (i definiuje szablon adresu URL do użycia w przypadku GET), <link type="text/css">jest GET ... itd. W ten sposób przeglądarki mogą poruszać się po dowolnej ustrukturyzowanej stronie HTML i Internecie.

Cały punkt, który zrobiłeś

  • jakich parametrów zapytania można użyć i ich możliwych wartości
  • struktura JSON / XML / dowolne dokumenty, które musisz wysłać w swoich żądaniach POST / PATCH / etc
  • struktura odpowiedzi wysłanej przez serwer
  • możliwe błędy, które mogą wystąpić

Są to punkty, które powinny zostać uwzględnione w definicji znormalizowanego typu mediów . Oczywiście jest to o wiele trudniejsze i nie jest to coś, o czym myśli większość ludzi, definiując interfejs API „REST”. Nie możesz po prostu zabrać jednostek biznesowych i wrzucić ich atrybutów do dokumentu JSON, aby mieć interfejs API RESTful.

Oczywiście zdarzyło się, że REST został w jakiś sposób osłabiony, co oznacza „używaj HTTP zamiast skomplikowanego SOAPy”. Samo użycie HTTP i HyperText nie wystarczy, by być ODPOCZYNEKIEM, większość ludzi się myli.

Nie jest to konieczne złe rzeczy: REST poświęcają wydajność i łatwość rozwoju w zamian za długoterminową łatwość konserwacji i ewolucję. Został stworzony do integracji aplikacji dla dużych przedsiębiorstw. Mały internetowy interfejs API z zakodowaną strukturą JSON może być tym, czego potrzebujesz. Po prostu nie nazywaj go REST, to internetowy interfejs API ad hoc, nic więcej. A to nie znaczy, że jest do bani, po prostu oznacza, że ​​nie próbuje przestrzegać ograniczenia REST.

Dalsza lektura

Mam nadzieję, że ta pomoc trochę wyjaśni :)

Laurent Bourgault-Roy
źródło
2

Istnieje kilka formatów Hypermedia, które starają się zapewnić bogatsze odpowiedzi, które zawierają więcej informacji na temat rodzaju żądań do wysłania, i nic nie stoi na przeszkodzie, aby wzbogacić odpowiedź o jeszcze więcej informacji.

Oto przykładowy dokument Syreny :

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

Jak widać, w wiadomości znajdują się informacje o tym, jak nawiązać połączenie actions, a następnie interpretując te informacje, klient staje się bardziej odporny na zmiany.

Staje się szczególnie silny, jeśli relsą URI, które można wyszukać, a nie z ustalonego słownictwa.

mcintyre321
źródło
0

Gdzie przeczytałeś, że „dokumentacja nie jest już potrzebna” dla usług HATEAOS? Jak mówisz, nadal musisz udokumentować semantykę linków. Jednak dzięki HATEOAS nie musisz dokumentować, a zatem zachować na zawsze strukturę większości URI.

HATEOAS umożliwia implementatorowi usługi znaczną i wydajną modyfikację i skalowanie implementacji bez zmiany niewielkiego zestawu identyfikatorów URI, od których zależy klient. Łatwiej jest zachować niewielką liczbę punktów wejścia bez zmian niż duży zestaw. Stąd zmniejszenie liczby publicznych punktów wejścia do usługi i dynamiczne dostarczanie łączy do pod-zasobów (HATEOAS) faktycznie obsługuje „fajne identyfikatory URI nie zmieniają się” lepiej niż usługi inne niż HATEOAS.

Jonathan Giddy
źródło
Jednym z miejsc, w których można przeczytać, że „dokumentacja nie jest już potrzebna”, jest rozprawa Roya Fieldinga, który wymyślił ten termin.
meriton - podczas strajku
1
Właśnie przeszukałem rozprawę Fieldinga pod kątem zastosowania „dokumentacji” i nie znalazłem niczego, co przypominałoby stwierdzenie „dokumentacja nie jest już potrzebna”. Czy możesz wskazać, gdzie w rozprawie Fieldinga znalazłeś to roszczenie?
Jonathan Giddy,
0

(HATEOAS), ograniczenie, które ma sprawić, że interfejs API sieci Web będzie „naprawdę RESTful”

Jedyne, co czyni go prawdziwym interfejsem API REST, to spełnianie wszystkich ograniczeń, a nie tylko jednego.

Ale moim zdaniem usługa to znacznie więcej niż jej struktura URI. Aby korzystać z niego skutecznie, musisz także wiedzieć: ...

Dlatego potrzebujemy innych ograniczeń, samoopisowego komunikatu itp.

Aby uniknąć łamania klientów, nadal musisz zaktualizować swój interfejs API.

Bez względu na to, jak spróbujesz, musisz zaktualizować interfejs API. W kliencie REST nadal musisz wiedzieć, jak dostać się do strony, na której chcesz robić rzeczy, które linki należy śledzić i jakie właściwości musisz zebrać na podstawie słownika RDF opisującego komunikat. Jeśli musisz wymienić lub usunąć coś z tego słownika, prawdopodobnie spowoduje to uszkodzenie wszystkich twoich klientów i będziesz potrzebować nowej wersji. Myślę więc, że REST nie jest czymś, co powinieneś opublikować wcześniej (i wymyśl model, gdy ciągle zmieniasz API), w przeciwnym razie będziesz mieć wiele wersji. Najpierw potrzebujesz stabilnego modelu domeny, na którym możesz ...

inf3rno
źródło