Cosa offre HATEOAS per la rilevabilità e il disaccoppiamento oltre alla possibilità di modificare la struttura dell'URL più o meno liberamente?


62

Ultimamente ho letto di Hypermedia come Engine of Application State (HATEOAS), il vincolo che si dice abbia reso l'API Web "veramente RESTful". Si riduce sostanzialmente a includere collegamenti con ogni risposta alle possibili transizioni che è possibile effettuare dallo stato corrente.

Permettetemi di illustrare ciò che HATEOAS si basa sulla mia comprensione - e per favore correggetemi se ho perso qualcosa.

/
    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" }
        }
    }

Si dice che HATEOAS offra due vantaggi principali:

  1. L'intero servizio è rilevabile a partire dall'URI principale, non è più necessaria la documentazione.

  2. Il client è disaccoppiato dal server che ora può cambiare liberamente la struttura dell'URI. Ciò elimina la necessità di versionare le API.

Ma dal mio punto di vista, un servizio è molto più della sua struttura URI. Per usarlo in modo efficace, devi anche sapere:

  • quali parametri di query è possibile utilizzare e i loro possibili valori
  • la struttura di JSON / XML / qualunque documento sia necessario inviare nelle richieste POST / PATCH / etc
  • la struttura della risposta inviata dal server
  • i possibili errori che potrebbero verificarsi
  • ...

Sulla base di quanto sopra, HATEOAS risolve solo una minima parte dei problemi di rilevabilità e accoppiamento. È ancora necessario documentare i quattro aspetti precedenti e i client saranno comunque fortemente accoppiati al server a causa loro. Per evitare la rottura dei client, è comunque necessario eseguire la versione dell'API.

L'unico vantaggio che offre è che puoi modificare la struttura del tuo URL più o meno liberamente (a proposito, cosa è successo al principio "I cool URI non cambiano" ?). La mia comprensione è corretta?

Risposte:


47

Penso che il tuo istinto sia in gran parte corretto; quei vantaggi proclamati non sono poi così grandi, come per qualsiasi applicazione web non banale che i clienti dovranno preoccuparsi della semantica di ciò che stanno facendo e della sintassi.

Ciò non significa che non dovresti fare in modo che la tua applicazione segua i principi di HATEOAS!

Cosa significa veramente HATEOAS ? Significa strutturare la tua applicazione in modo che sia in linea di principio simile a un sito Web e che tutte le operazioni che potresti voler fare possano essere scoperte senza dover scaricare alcuni schemi complessi. (I sofisticati schemi WSDL possono coprire tutto, ma quando lo fanno, hanno superato la capacità di quasi tutti i programmatori di capire, figuriamoci di scrivere! Puoi vedere HATEOAS come una reazione contro tale complessità.)

HATEOAS non significa solo rich link. Significa usare i meccanismi di errore dello standard HTTP per indicare più esattamente cosa è andato storto; non devi semplicemente rispondere con “waaah! no "e può invece fornire un documento che descriva ciò che era effettivamente sbagliato e cosa il cliente potrebbe fare al riguardo. Significa anche supportare cose come le richieste OPTIONS (il modo standard per consentire ai clienti di scoprire quali metodi HTTP possono usare) e la negoziazione del tipo di contenuto in modo che il formato della risposta possa essere adattato a un modulo che i clienti possono gestire. Significa inserire un testo esplicativo(o, più probabilmente, collegamenti ad esso) in modo che i client possano cercare come utilizzare il sistema in casi non banali se non lo sanno; il testo esplicativo potrebbe essere leggibile dall'uomo o potrebbe essere leggibile da una macchina (e può essere complesso come vuoi). Infine, significa che i client non sintetizzano i collegamenti (ad eccezione dei parametri di query); i clienti useranno un collegamento solo se glielo hai detto.

Devi pensare di far navigare il sito da un utente (che può leggere JSON o XML anziché HTML, quindi un po 'strano) con una grande memoria per i collegamenti e una conoscenza enciclopedica degli standard HTTP, ma per il resto nessuna conoscenza di cosa fare fare.

E, naturalmente, puoi utilizzare la negoziazione del tipo di contenuto per offrire un client HTML (5) / JS che consentirà loro di utilizzare la tua applicazione, se è quello che il loro browser è disposto ad accettare. Dopotutto, se la tua API RESTful è buona, dovrebbe essere “banale” implementarla sopra?


6

Il fatto è che HATEOAS deve presentare un secondo pilastro che definisce cosa sia un'API RESTful: tipo di supporto standardizzato. Disse Roy stesso

Un'API REST dovrebbe dedicare quasi tutto il suo sforzo descrittivo alla definizione dei tipi di media utilizzati per rappresentare le risorse ".

Con un tipo di supporto standardizzato che definisce esplicitamente la transizione e ipertesto per indirizzare le risorse tra loro, è possibile creare un grafico delle risorse che può assumere qualsiasi forma senza interrompere alcun client. Come il lavoro sul web, davvero: hai un collegamento tra documento e i documenti sono scritti in HTML che definiscono come seguire quei collegamenti. <a href>è un GET, <form>è GET o POST (e definisce il modello di url da utilizzare in caso di GET), <link type="text/css">è GET ... ecc. Ecco come i browser possono navigare in pagine HTML strutturate arbitrarie e sul Web.

Tutto il punto che hai sottolineato

  • quali parametri di query è possibile utilizzare e i loro possibili valori
  • la struttura di JSON / XML / qualunque documento sia necessario inviare nelle richieste POST / PATCH / etc
  • la struttura della risposta inviata dal server
  • i possibili errori che potrebbero verificarsi

Sono punti che dovrebbero essere affrontati dalla definizione del tipo di supporto standardizzato . Naturalmente, questo è molto più difficile e non qualcosa a cui la maggior parte delle persone pensa quando definiscono un'API "REST". Non puoi semplicemente prendere le tue entità aziendali e inserire i loro attributi in un documento JSON per avere un'API RESTful.

Ovviamente, ciò che è accaduto è che REST è stato in qualche modo diluito nel senso di "usare HTTP invece di complicate cose SOAPy". Usare HTTP e HyperText non è abbastanza per essere RESTful, questo è ciò che la maggior parte delle persone sbaglia.

Non che ciò sia necessario una cosa negativa: REST fa sacrificio di prestazioni e facilità di sviluppo in cambio di manutenibilità ed evolutività a lungo termine. È stato creato per l'integrazione di applicazioni di grande impresa. Una piccola API Web con struttura JSON codificata può essere ciò di cui hai bisogno. Basta non chiamarlo REST, è un'API Web ad hoc, niente di più. E questo non significa che faccia schifo, significa solo che non cerca di seguire il vincolo di REST.

Ulteriori letture

Spero che questo aiuto chiarisca un po ':)


2

Esistono alcuni formati Hypermedia che si sforzano di fornire risposte più ricche che includono ulteriori informazioni sul tipo di richieste da inviare e non c'è nulla che ti impedisca di arricchire la risposta con ancora più informazioni.

Ecco un esempio di documento 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" }
  ]
}

Come puoi vedere, le informazioni su come chiamare correlate actionssono fornite nel messaggio, e quindi interpretando queste informazioni, il cliente diventa più resistente al cambiamento.

Diventa particolarmente potente se relsono URI che possono essere cercati, piuttosto che da un vocabolario fisso.


0

Dove hai letto che "la documentazione non è più necessaria" per i servizi HATEAOS? Come dici tu, devi ancora documentare la semantica dei collegamenti. Tuttavia, con HATEOAS non è necessario documentare, e quindi conservare per sempre, la struttura della maggior parte degli URI.

HATEOAS consente a un implementatore di servizi di modificare e ridimensionare l'implementazione in modo significativo ed efficiente senza cambiare un piccolo set di URI da cui dipende il client. È più facile mantenere invariato un piccolo numero di punti di ingresso rispetto a un set di grandi dimensioni. Pertanto, ridurre il numero di punti di accesso pubblici al servizio e fornire dinamicamente collegamenti a risorse secondarie (HATEOAS) in realtà supporta "I cool URI non cambiano" meglio dei servizi non HATEOAS.


Un luogo in cui si può leggere che "la documentazione non è più necessaria" è la tesi di Roy Fielding, che ha coniato il termine.
meriton - in sciopero il

1
Ho appena cercato la tesi di Fielding per l'uso della "documentazione" e non ho trovato nulla che assomigli alla frase "la documentazione non è più necessaria". Puoi per favore indicare dove nella tesi di Fielding hai trovato questo reclamo?
Jonathan Giddy,

0

(HATEOAS), il vincolo che si afferma rendere un'API Web "veramente RESTful"

L'unica cosa che lo rende una vera API REST è soddisfare tutti i vincoli, non solo uno.

Ma dal mio punto di vista, un servizio è molto più della sua struttura URI. Per usarlo in modo efficace, devi anche sapere: ...

Ecco perché abbiamo bisogno di altri vincoli, messaggio auto-descrittivo, ecc ...

Per evitare la rottura dei client, è comunque necessario eseguire la versione dell'API.

Indipendentemente da come ci provi, dovrai eseguire la versione dell'API. In un client REST devi ancora sapere come arrivare a una pagina in cui vuoi fare cose, quali collegamenti seguire e quali proprietà devi raccogliere in base al vocabolario RDF che descrive il messaggio. Se devi sostituire o rimuovere qualcosa da quel vocabolario, probabilmente si romperanno tutti i tuoi client e avrai bisogno di una nuova versione. Quindi penso che REST non sia qualcosa che dovresti pubblicare in anticipo (e capire il modello mentre cambi costantemente l'API), altrimenti avrai molte versioni. È necessario prima un modello di dominio stabile su cui poter basarsi ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.