Qual é o objetivo do HATEOAS no lado do cliente?


35

Atualmente, como eu entendo, o HATEOAS é basicamente o envio de cada link de resposta com informações sobre o que fazer em seguida. Um exemplo simples é facilmente encontrado na internet: um sistema bancário juntamente com um recurso da conta. O exemplo mostra esta resposta após uma solicitação GET para um recurso de conta

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>

Juntamente com os dados, existem links informando o que pode ser feito a seguir. Se o saldo for negativo, temos

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>

Para que possamos apenas depositar. Tudo bem, se estamos usando o Fiddler ou fazendo solicitações com o navegador, podemos ver facilmente o que pode ser feito. Esse tipo de informação é útil para descobrirmos os recursos da API e o servidor é dissociado do cliente.

O ponto, no entanto, é que, quando construímos um cliente, como um SPA com Javascript, um aplicativo Android ou muitas outras coisas, não consigo ver como o HATEOAS continua sendo relevante. O que quero dizer é o seguinte: quando estou codificando o SPA em javascript, preciso saber o que pode ser feito na API para escrever o código.

Então, eu preciso conhecer os recursos, os métodos suportados, o que eles esperam receber e o que devolvem para gravar as chamadas ajax no servidor e até para criar a interface do usuário. Quando crio a interface do usuário, devo saber que, depois de solicitar a conta, é possível, por exemplo, depositar nela, ou não poderei fornecer essa opção na interface do usuário. Além disso, precisarei conhecer o URI para fazer o depósito e criar a chamada ajax.

O que quero dizer é que, quando fazemos solicitações para a API, os links permitem descobrir e usar melhor a API, mas quando construímos um cliente, o aplicativo que estamos construindo não olha apenas para os links e depois renderiza sozinho a interface do usuário correta e faça as chamadas ajax corretas.

Então, como a HATEOAS é importante para os clientes? Por que nos incomodamos com o HATEOAS?


11
Você está certo, mas esse não é o ponto. O HATEOAS impede que você precise construir os URIs para os links na página do cliente.
James McLeod

Respostas:


24

o aplicativo que estamos construindo não irá simplesmente olhar para os links e, por si só, renderizar a interface do usuário correta e fazer as chamadas ajax corretas

Na verdade, este é exatamente o que HATEOAS vai dar a interface do usuário. Não é o que é possível, mas quando é possível. Um HATEOAS formal como o HAL , como a pergunta indica, fornece links que indicam o que é possível. Mas quando esses links aparecerem, depende do estado do aplicativo. Portanto, os links podem mudar no recurso ao longo do tempo (com base em ações que já foram executadas).

Isso nos permite criar uma interface do usuário que contenha todos os estados possíveis , mas não nos preocupemos quando esses estados se tornarem ativos. Por exemplo, a presença do rel="deposit"pode informar diretamente a interface do usuário quando estiver OK para renderizar o make depositformulário. O que permite ao usuário inserir um valor e enviar usando o link.


2
Portanto, ao criar a interface do usuário, ainda precisamos saber tudo o que a API oferece e, olhando para esses links, podemos saber o estado em que estão as informações no servidor? Por exemplo, a interface do usuário sabe que é possível depositar, retirar, transferir ou fechar (conhece os possíveis rels) e verifica o que voltou para ver o estado?
User1620696

11
Sim, poderia. Mais uma vez, depende de quão dinâmico você deseja tomá-lo. Como outros já mencionaram, a capacidade de alterar links no servidor (e não interromper clientes) é outra vantagem. E isso se torna muito interessante quando sua API tem clientes iPhone, Android, Windows Phone, Mobile Web e Web que todos a usam (sem mencionar se sua API é publicada para outras pessoas criarem clientes).
Davin Tryon

@ user1620696 Você deve saber tudo isso de qualquer maneira, através do cliente e do servidor, subestimando o tipo de conteúdo, se for o caso. O tipo de conteúdo é muito mais do que xml burro ou Json. Você deve ter algum "depósito bancário" tipo de conteúdo que o cliente entender como trabalhar com
Cormac Mulhall

11
O @Nik dá uma olhada no HAL para obter um exemplo de como os links são fornecidos na resposta.
Davin Tryon em

11
Sim, você ainda tem problemas de compatibilidade com versões anteriores. Isso pode ser resolvido incluindo um cabeçalho ou versão da versão no URL. Mas, eu diria que você está entendendo corretamente.
Davin Tryon 25/01

3

Atualmente, como eu entendo, o HATEOAS é basicamente o envio de links de resposta com informações sobre o que fazer a seguir

HATEOAS é muito mais do que apenas links. É "hiper mídia" como o mecanismo do estado do aplicativo.

O que está faltando em sua descrição é o tipo de conteúdo, a definição formal da hiper mídia que é transmitida entre cliente e servidor.

HTML é um exemplo de hipermídia e um exemplo de por que o HATEOS funciona. A própria página HTML é o mecanismo que permite ao cliente (ou seja, o usuário) percorrer o site. Um navegador com apenas a capacidade de tornar o HTML presente para o usuário um site totalmente navegável. Não é apenas o fato de transmitir links para as outras páginas, mas de maneira significativa, contextualizando os links e de maneira a permitir que o navegador construa um site navegável.

E o mais importante é que o navegador pode fazer isso com o ZERO, com uma compreensão antecipada do próprio site. O navegador conhece apenas HTTP e HTML. Com base nesse entendimento simples, ele pode apresentar o New York Times ao usuário para navegar.

Isso ocorre mesmo que o "usuário" seja outro programa de computador. A hiper mídia em si deve definir o contexto da navegação.


11
Isso não significa que você deve criar um cliente tão complexo (e propenso a erros) quanto um navegador? Flexibilidade muitas vezes vem com a complexidade como um custo ...
Andres F.

@AndresF. isso não significa que você deve ou deve fazê-lo, apenas oferece a opção de fazê-lo dinamicamente, se você quiser ou precisar.
Peteris

2
@nik Claro. De cabeça para baixo, imagine que você tem um serviço que fornece informações sobre ancestralidade por meio de uma API repousante. Você tem um tipo de conteúdo que define o formato de um recurso de 'Pessoa' que possui várias informações sobre eles, mas também define como são os relacionamentos, digamos 'irmão' ou 'irmã' ou 'mãe' etc. Como essa é a hipermídia, esses relacionamentos simplesmente tenha um URI para outro recurso da Pessoa. Um cliente bastante simples usando os verbos HTTP e entendendo esse tipo de conteúdo 'Pessoa' pode navegar por essa API. Digamos que você queira encontrar todos os descendentes diretos de uma pessoa em particular.
Cormac Mulhall

2
@nik Esse cliente precisa entender simplesmente o tipo de conteúdo do recurso que ele acessou e os verbos HTTP (GET, PUT, DELETE etc.) e você pode navegar por esses recursos de busca e atualização da API. E, mais importante, qualquer cliente que entenda o tipo de conteúdo pode pular, via um URI, para outro servidor completamente e continuar como estava. Eles não se importam com o servidor com o qual estão conversando, apenas se preocupam com o tipo de conteúdo do recurso, entendem ou não.
Cormac Mulhall

11
@ Nik Assim, nessa situação, você tem um servidor que entende o tipo de conteúdo original (por exemplo, Pessoa v1) e o novo tipo de conteúdo (Pessoa v2). O cliente entende apenas a Pessoa v1. O cliente informa ao servidor quais tipos de conteúdo ele entende por meio do cabeçalho Accept em HTTP. Usando a negociação de conteúdo, o servidor determina se enviará o que o cliente suporta; nesse caso, ele retornará o recurso usando o tipo de conteúdo Pessoa v1. Agora você pode simplesmente parar de oferecer suporte a esse tipo de conteúdo antigo e pode enviar ao cliente um erro 406. É melhor tentar e apoiar o máximo que puder.
Cormac Mulhall

2

Você não precisa criar uma interface gerada dinamicamente. Embora possa ser bom, não é necessário. Se você não pode construir uma interface dinâmica, basta usar os links e pronto. A desvantagem é que você está novamente vinculado ao back-end e travará se algo mudar.

Usar o layout dinâmico pode ser bem simples:

links.forEach(function(link) {

  switch(link.rel) {

    case 'deposit':
      showDepositButton();
      break;

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

});

Ele economiza seu código de cliente como:

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

Você pode implementar uma posição negativa permitida (emprestando dinheiro, por exemplo) sem alterar seu cliente.


Como um exemplo um pouco mais forte, o banco pode oferecer limites de cheque especial variável em suas contas, sem precisar informar ao lado do cliente qual é o limite em cada conta.
Bart van Ingen Schenau

Correto, você pode tomar a decisão dos limites de saldo tão complexa quanto desejar e ainda não precisa fazer alterações no cliente. Se você levar isso adiante com partes do REST, como o tipo de conteúdo, poderá exibir visualizações diferentes. Por exemplo, uma conta parece diferente de uma transação. Também é interessante o código sob demanda (embora não muito implementado). Isso poderia ser usado, por exemplo, para um estimador de empréstimos. Ele pode fornecer à interface uma função simples de calculadora, para que o cliente precise implementar apenas as entradas para o cálculo. Ele ficará atualizado a partir do back-end.
Luc Franken

2
Mas geralmente o cliente precisa saber POR QUE não pode retirar, portanto ainda precisamos enviar um ENUM ou String em um campo separado para o cliente reason. E se ainda precisamos disso, por que não simplesmente enviar a ele outro campo booleano em canWithdrawvez de um link para a ação? Outra vantagem é a capacidade de alterar o URL de uma ação sem tocar no cliente. Mas .. qual o motivo para alterar a URL? Na maioria dos casos, também há alguma mudança na semântica ou nos parâmetros ou na forma de solicitação / resposta, etc. Portanto, precisamos mudar o cliente. Então, eu ainda não entendi - qual é o objetivo do HATEOAS.
Ruslan Stelmachenko
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.