Qual è il punto con HATEOAS sul lato client?


35

Come capisco attualmente, HATEOAS si basa essenzialmente sull'invio insieme a ciascun link di risposta con informazioni su cosa fare dopo. Un semplice esempio è facilmente reperibile su Internet: un sistema bancario insieme a una risorsa di conto. L'esempio mostra questa risposta dopo una richiesta GET a una risorsa dell'account

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>

Insieme ai dati ci sono collegamenti che dicono cosa si può fare dopo. Se il saldo è negativo, abbiamo

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>

In modo che possiamo solo depositare. Va bene, se stiamo usando Fiddler o stiamo facendo richieste con il browser possiamo facilmente vedere cosa si può fare. Questo tipo di informazioni è utile per noi per scoprire le capacità dell'API e il server viene disaccoppiato dal client.

Il punto, tuttavia, è che quando costruiamo un client, come una SPA con Javascript, o un'app Android o molte altre cose, non riesco a vedere come HATEOAS continui ad essere rilevante. Quello che intendo è il seguente: quando sto codificando la SPA in javascript, devo sapere cosa si può fare nell'API per scrivere il codice.

Quindi ho bisogno di conoscere le risorse, i metodi supportati, cosa si aspettano di ricevere e cosa restituiscono per poter scrivere le chiamate Ajax sul server e persino per costruire l'interfaccia utente. Quando creo l'interfaccia utente, devo sapere che dopo aver richiesto l'account, ad esempio, si può depositare in esso o non sarò in grado di fornire questa opzione sull'interfaccia utente. Inoltre, dovrò conoscere l'URI per effettuare il deposito per creare la chiamata ajax.

Quello che voglio dire è che quando facciamo richieste all'API, i collegamenti ci permettono di scoprire e usare meglio l'API, ma quando costruiamo un client, l'app che stiamo costruendo non guarderà semplicemente i collegamenti e quindi renderà da soli l'interfaccia utente corretta ed effettua le giuste chiamate ajax.

Quindi, quanto è importante HATEOAS per i clienti? Perché ci preoccupiamo comunque di HATEOAS?


1
Hai ragione, ma non è questo il punto. HATEOAS ti impedisce di dover costruire gli URI per i collegamenti nella pagina sul client.
James McLeod,

Risposte:


24

l'app che stiamo costruendo non guarderà semplicemente i collegamenti e quindi da sola renderà l'interfaccia utente corretta ed effettuerà le giuste chiamate ajax

In realtà, questo è esattamente ciò che hateoas vi darà l'interfaccia utente. Non è ciò che è possibile, ma quando è possibile. Un HATEOAS formale come HAL , come afferma la domanda, fornisce collegamenti che indicano ciò che è possibile. Ma quando vengono visualizzati quei collegamenti dipende dallo stato dell'applicazione. Pertanto, i collegamenti possono cambiare nel tempo sulla risorsa (in base alle azioni che sono già state eseguite).

Questo ci consente di creare un'interfaccia utente che contenga tutti gli stati possibili , ma non preoccuparci di quando tali stati diventano attivi. Ad esempio, la presenza di rel="deposit"può indicare direttamente all'interfaccia utente quando è corretto eseguire il rendering del make depositmodulo. Che quindi consente all'utente di inserire un valore e inviare utilizzando il collegamento.


2
Quindi quando creiamo l'interfaccia utente dobbiamo ancora sapere tutto ciò che offre l'API, e quindi guardando quei collegamenti siamo in grado di conoscere lo stato in cui si trovano le informazioni sul server? Quindi, ad esempio, l'interfaccia utente sa che è possibile depositare, prelevare, trasferire o chiudere (conosce le possibili relazioni), quindi controlla cosa è tornato per vedere lo stato?
user1620696

1
Sì, potrebbe. Ancora una volta dipende da quanto dinamico vuoi prenderlo. Come altri hanno già detto, la possibilità di modificare i collegamenti sul server (e non rompere i client) è un altro vantaggio. E questo diventa molto interessante quando l'API ha un iPhone, Android, Windows Phone, Web mobile e client Web che la usano tutti (per non parlare del fatto che l'API sia pubblicata per altri utenti su cui costruire client).
Davin Tryon,

@ user1620696 Dovresti sapere tutto questo comunque sia attraverso il client che il server sottovalutando il tipo di contenuto se la risoluzione. Il tipo di contenuto è molto più di un muto xml o Json. Dovresti avere un tipo di contenuto "deposito bancario" che il cliente capisce come lavorare
Cormac Mulhall,

1
@Nik dai un'occhiata a HAL per un esempio di come vengono forniti i collegamenti nella risposta.
Davin Tryon,

1
sì, hai ancora problemi di compatibilità con le versioni precedenti. Ciò può essere risolto includendo un'intestazione della versione o una versione nell'URL. Ma direi che stai capendo correttamente.
Davin Tryon,

3

Come capisco attualmente, HATEOAS si basa essenzialmente sull'invio insieme a ciascun link di risposta con informazioni su cosa fare dopo

HATEOAS è molto più di un semplice link. È "hyper media" come motore dello stato dell'applicazione.

Ciò che manca nella descrizione è il tipo di contenuto, la definizione formale dell'hyper media che viene passato tra client e server.

HTML è un esempio di hyper media e un esempio del motivo per cui HATEOS funziona. La stessa pagina HTML è il motore che consente al client (ovvero all'utente) di spostarsi nel sito. Un browser con la sola capacità di rendere HTML presente all'utente un sito Web completamente navigabile. Non si limita semplicemente a passare i collegamenti alle altre pagine, ma li passa in un modo significativo che dà contesto ai collegamenti e in un modo che consente al browser di costruire un sito navigabile.

E, soprattutto, il browser può farlo con ZERO a conoscenza del sito Web stesso. Il browser conosce solo HTTP e HTML. Sulla base di questa semplice comprensione, può presentare all'utente il New York Times.

Ciò vale anche se l '"utente" è un altro programma per computer. L'hyper media stesso dovrebbe definire il contesto di navigazione.


1
Questo non significherebbe che devi costruire un client complesso (e soggetto a bug) come un browser? La flessibilità spesso comporta la complessità come costo ...
Andres F.

@AndresF. non significa che devi o dovresti farlo, ti dà semplicemente la possibilità di farlo in modo dinamico se lo desideri o ne hai bisogno.
Peteris,

2
@nik Certo. Dall'alto della mia testa immagino che tu abbia un servizio che fornisce informazioni sugli antenati tramite API riposanti. Hai un tipo di contenuto che definisce il formato di una risorsa 'Persona' che ha varie informazioni su di loro ma definisce anche come appaiono le relazioni, ad esempio 'fratello' o 'sorella' o 'madre' ecc. Perché questo è ipermedia quelle relazioni semplicemente avere un URI per un'altra risorsa Persona. Un client abbastanza semplice che utilizza i verbi HTTP e comprende questo tipo di contenuto "Persona" può navigare attraverso questa API. Supponi di voler trovare tutti i discendenti diretti di una determinata persona.
Cormac Mulhall,

2
@nik Questo client deve comprendere semplicemente il tipo di contenuto della risorsa a cui ha avuto accesso e i verbi HTTP (GET, PUT, DELETE ecc.) e puoi navigare attraverso questa API recuperando e aggiornando le risorse. E, soprattutto, qualsiasi client che comprende il tipo di contenuto può passare, tramite un URI, a un altro server e continuare così com'era. A loro non importa con quale server stanno parlando, si preoccupano solo del tipo di contenuto della risorsa, lo capiscono o no.
Cormac Mulhall,

1
@Nik Quindi in una situazione del genere hai un server che comprende il tipo di contenuto originale (ad esempio Persona v1) e il nuovo tipo di contenuto (Persona v2). Il client comprende solo la persona v1. Il client comunica al server quali tipi di contenuto comprende tramite l'intestazione Accept in HTTP. Utilizzando la negoziazione del contenuto, il server determina se invierà ciò che il client supporta, nel qual caso restituirà la risorsa utilizzando il tipo di contenuto Person v1. Ora potresti voler semplicemente smettere di supportare questo vecchio tipo di contenuto e puoi inviare al client un errore 406. È meglio provare e supportare il più possibile.
Cormac Mulhall

2

Non è necessario creare un'interfaccia generata dinamicamente. Anche se potrebbe essere bello, non è richiesto. Se non riesci a creare un'interfaccia dinamica, usa semplicemente i collegamenti e il gioco è fatto. Lo svantaggio è che sei di nuovo fortemente collegato al backend e andrà in crash se qualcosa cambia.

L'uso del layout dinamico può essere abbastanza semplice tra l'altro:

links.forEach(function(link) {

  switch(link.rel) {

    case 'deposit':
      showDepositButton();
      break;

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

});

Ti salva nel tuo codice cliente come:

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

È possibile implementare una posizione negativa consentita (prendendo ad esempio denaro in prestito) senza cambiare cliente.


Come esempio leggermente più forte, la banca può offrire limiti di scoperti variabili sui propri conti, senza dover dire al cliente quale sia il limite su ciascun conto.
Bart van Ingen Schenau,

Corretto, è possibile rendere la decisione dei limiti di equilibrio complessa come si desidera e tuttavia non è necessario apportare modifiche al cliente. Se vai oltre con parti REST come il tipo di contenuto, puoi mostrare diverse visualizzazioni. Ad esempio, un account ha un aspetto diverso da una transazione. Interessante anche il codice su richiesta (anche se non molto implementato). Ciò potrebbe essere utilizzato ad esempio per uno stimatore del prestito. Può fornire all'interfaccia una semplice funzione di calcolatrice, quindi il cliente deve solo implementare gli input per il calcolo. Rimarrà aggiornato dal back-end.
Luc Franken

2
Ma di solito il cliente deve sapere PERCHÉ non può ritirarsi, quindi dobbiamo ancora inviare un ENUM o una stringa in un campo separato al cliente reason. E se abbiamo ancora bisogno di questo, perché non inviargli semplicemente un altro campo booleano canWithdrawinvece di un link all'azione? Un altro vantaggio è la possibilità di modificare l'URL di un'azione senza toccare il client. Ma .. quale motivo per cambiare l'URL? Nella maggior parte dei casi cambia anche qualche semantica o parametri o forma di richiesta / risposta ecc. Quindi dobbiamo comunque cambiare il client. Quindi, ancora non capisco - che senso ha HATEOAS.
Ruslan Stelmachenko,
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.