REST 101 – Parte 2

Publicado em 01/12/2010

2


Olá galera, tudo certin?

Como vocês devem ter percebido, a freqüência com que publico novos posts aqui no blog caiu um bocado. Isso ocorreu devido a um aumento, não planejado, de estudos que estou realizando em meu tempo livre. Pretendo, aos poucos, retomar o ritmo original de postagens. De qualquer forma, estou disponível no twitter.

Para quem chegou de marte agora (motivação)

Ministrei uma palestra no DNAD desse ano (grande honra!), sobre REST. Nessa palestra me comprometi a tratar mais do assunto aqui no blog.

Na semana passada, escrevi um primeiro post sobre o assunto, bem prático, demonstrando como implementar um serviço REST simples (CRUD) usando .NET (WCF). Naquele momento, tentei me restringir apenas a alguns poucos conceitos. Hoje, pretendo avançar um pouco mais. Pretendo falar, por exemplo, sobre HATEOAS.

Se o post anterior foi extremamente prático, focado em implementação (código), este é um pouco mais conceitual, dirigido a representação dos recursos.

Mas .. antes de avançarmos…

Alguns conceitos fundamentais já entendidos

  • Recurso: de forma abstrata e orientada ao contexto de serviços Web, é qualquer conteúdo (informação) disponível no host do serviço web ou que precise ser enviado para este. Além disso, todo recurso é endereçavel.

  • Representação: é uma descrição de um recurso. Para que um consumidor (cliente) de um serviço web possa obter informações sobre um recurso, obterá isso mediante uma representação. Por exemplo, os dados de um cliente (recurso) podem ser representadas como um bloco de texto, um documento xml, um XHTML, um corpo de conteúdo JSON …

  • URI: URI é o nome do endereço de um recurso na Web. Se um recurso não tiver uma URI, não estará na Web. Logo, não será um recurso.

  • Interface uniforme: em toda a Web existem apenas algumas coisas básicas que você pode fazer com um recurso. O HTTP define quatro operações fundamentais GET, POST, PUT e DELETE. Esse corpo padrão de operações é definido como interface uniforme.

O que encontramos em uma representação de recurso

No post anterior criamos um recurso muito simples (Contato – com nome, email e Id). Além disso, criamos uma representação muito simples para esse recurso (XML gerado automaticamente pelo DataContractSerializer).

O que pode haver em uma representação de um recurso? Até agora, a resposta evidente é:

  • os valores dos elementos de informação que pertencem a esse recurso;

Entretanto, há alguns outros tipos de conteúdo que podem ser representados, vejamos:

  • links para recursos relacionados;
  • links que representam uma transição do estado presente da aplicação para um estado futuro (aqui está a chave do HATEOAS);
  • resultados da execução de quaisquer regras de negócio que se relacionem com o recurso relacionado a outros recursos locais.

vamos começar do simples…

Links? Por que links?

Nem um objeto (recurso) é uma ilha. Todo recurso está relacionado, de alguma forma, com outros recursos. Isso nos deixa três escolhas:

  1. incluir, integralmente, a representação do recurso associado na representação  do recurso que estamos representando;
  2. incluir um link para a representação do recurso associado;
  3. não incluir nem a representação integral, nem um link para o recurso associado.

A primeira opção é indicada quando o recurso associado é uma espécie de value-object (DDD). Entretanto, não seria apropriada para entidades.

A segunda opção é claramente superior para entidades.

A terceira é “horrível” sempre!

Alegre

Regras de negócio que relacionam um recurso com outros recursos devem fazer referência apenas para recursos locais. Isso permite identificar e prevenir dependências circulares onde o estado do recurso A é parcialmente definido pelo estado do recurso B, que por sua vez é parcialmente definido pelo recurso A (e entramos em loop).

Podemos sempre organizar os recusos locais de forma a prevenir dependências circulares. Isso não é possível de garantir com recursos providos por outros serviços.

Resultados da execução de quaisquer regras de negócio…?

Sim! Há informações sobre um recurso que são “calculadas” Alegre

O estado de uma ordem de venda, por exemplo, é, em parte, uma função do estado de uma cópia local de uma ordem de compra associada; alterações na ordem de compra afetarão o estado da ordem de venda na próxima vez que as regras comerciais que governam o estado de a ordem de venda forem avaliadas (ou seja, na próxima vez que uma representação da ordem de vendas for gerada)

Importante, as regras que controlam o estado de um recurso são internas para o serviço que provê o recurso: elas não são disponibilizadas para os consumidores. Em outras palavras, o estado do recurso é uma função de um conjunto privado de regras que somente o dono do recurso conhece. Essas regras não devem “vazar” para a representação externa.

Links que representam transição de estado?

Sim outra vez! Mas essa precisa de algumas informações adicionais… Aqui estamos falando de HATEOAS! E antes de falar sobre HATEOAS, temos que entender o conceito de Hypermedia.

Defindindo Hypermedia para o conceito desse post

Antes de ofender algum puritano. Deixo claro, desde já, que a definição que utilizo para Hypermedia é significativamente mais restrita do que aquela proposta originalmente por Ted Neldson.

Para essa discussão, considero Hypermedia como uma extensão lógica do termo hypertext em que gráficos, áudio, vídeo, texto e hyperlinks se relacionam para criar um conteúdo geralmente não-linear.

O princípio da Hypermedia (Hypermedia tenet)

Ao navegar na internet, nos movemos entre páginas clicando em links ou preenchendo e enviando formulários. Embora, na maioria dos casos não nos demos conta disso, esse conjunto de páginas inter-relacionadas por links descrevem um protocolo. Ou seja, um conjunto de passos (ações) que precisamos cumprir para atingir um objetivo. Eis o princío da Hypermedia!!

Hypermedia: por meio de links, navegamos por recursos, mudando o estado de uma aplicação.

Hypermedia é parte comum de nossas atividades online diárias. Entretanto, mesmo com essa familiaridade, é raramente usada em interações “computer-to-computer”.

Embora o trabalho de doutorado de Fielding sobre REST tenha dado destaque a essa característica, o conceito ainda não “amadureceu” nas implementações atuais. O conceito definido por Fielding foi denominado HATEOAS…

Vamos ao conceito…

Hypermedia As The Engine of Application State

A expressão Hypermedia As The Engine of Application State, algumas vezes abreviada para HATEOAS, é utilizada para descrever um conceito básico do estilo arquitetural REST. Pessoalmente, prefiro me referir a esse conceito por Hypermidia tenet (princípio) ou simplesmente Hypermedia.

Colocado de forma simples, esse princípio afirma que hypermedia é uma alternativa poderosa para mudança do estado de uma aplicação. Mas… o que vem a ser o estado de uma aplicação?

.. Vamos por partes. Podemos entender uma aplicação como sendo um “comportamento computadorizado”. Ou seja, a execução de uma série de etapas (passos), executadas em uma ordem determinada, para o atingimento de um objetivo. Certo? Tomando alguma liberdade, poderíamos chamar de protocolo de aplicação esse conjunto de interações que são necessárias para o atingimento desse objetivo. Ok? O estado de uma aplicação é uma espécie snapshot (foto instantânea) de um momento de execução desse tipo de protocolo de aplicação.

Acho que fica mais fácil se explicarmos com um exemplo:

Estamos desenvolvendo um serviço que sirva como base para um comércio eletrônico. O processo de compra possui diversos estágios:

  • seleção do produto;
  • escolha da forma de pagamento;
  • confirmação do pagamento;
  • expedição;

apenas para citar uns poucos passos… Até concluir a compra, o cliente terá diversas interações com o serviço (avançando rumo ao objetivo da aplicação). Em cada uma dessas interações irá ocorrer uma mudança de estado. Certin?

O conceito HATEOAS indica que cada estado de aplicação implica em um recurso que o representa. Além disso, na representação desse recurso, deverá existir links que encaminhem para a composição ou construção de um recurso que implique na transição do estado.

Simples assim!

Construindo serviços REST orientados a Hypermedia

Um sistema baseado em hypermedia é caracterizado pela presença de links nas representações de recursos “trocadas” pelos participantes em um protocolo de aplicação. Tais links tornam públicos outros recursos que compõe o protocolo do aplicativo. Além disso, geralmente, são reforçados por uma marcação semântica que ajudam na compreensão do significado, no domínio, para o recurso indicado.

Para dar um exemplo, um consumidor inicia uma requisição para o ponto de entrada do serviço. O serviço trata essa requisição e responde com uma representação de recurso contendo uma série de links. O consumidor escolhe um desses links para avançar para o próximo estágio da interação. Através da execução de diversas interações, o consumidor avança em direção ao seu objetivo (usando links). Em outras palavras, a modificação do estado de uma aplicação ocorre pela interação do conjunto:

  • serviço;
  • consumidor;
  • troca de recursos com links (hypermedia-enabled);
  • publicação e seleção de links.

Em cada interação, o serviço e o consumidor trocam representações de estados de recurso, não do estado do aplicativo. Uma representação transferida inclui links que refletem o estado do aplicativo. Esses links legitimam as transições do estado do aplicativo. Entretanto, o estado do aplicativo não é registrado explicitamente na representação recebida pelo consumidor; ela pode ser inferida pelo consumidor com base no estado de todos os recursos, potencialmente distribuídos entre muitos serviços, com os quais o consumidor esteja, atualmente, interagindo.

Todo serviço HATEOAS impõe um protocolo (apresentando o conceito de DAP)

Um serviço que implemente o conceito de HATEOAS sempre impõe um protocolo – um protocolo de domínio da aplicação (Domain Application Protocol – DAP) – pela promoção e legitimação das interações entre recursos relevantes. Quando um consumidor segue os links contidos em uma representação de recurso e interage com os recursos relacionados, o estado global da aplicação se modifica.

Domain Application Protocols (DAPs) especificam interações entre um consumidor e um conjunto de recursos envolvidos em um processo de negócios. DAPs se baseiam no protocolo HTTP e relacionados para apoiar o atingimento dos objetivos de negócio. Serviços implementam DAPs adicionando hypermedia (links) nas representações de recurso. Esses links destacam outrso recursos com os quais um consumidor pode interagir para avançar em uma transação.

Consumidores em um sistema baseado em hymermedia causam alterações no estado da aplicação visitando e manipulando o estado dos recursos. Curiosamente, as mudanças no estado do aplicativo que resultam das ações de consumidor em um sistema hypermedia se assemelham a execução de um processo de negócio. Esse aspecto indica que nossos serviços podem “publicar” workflows usando hypermedia. Hypermedia torna fácil implementar protocolos de negócio de forma a reduzir o acoplamento entre consumidores e serviços.

Ao invés de compreender uma estrutura URI específicos, o consumidor só precisa entender o contexto semântico ou negócio em que aparece um link. Isso reduz a dependência de uma aplicação em metadados estáticos, como modelos de URI ou Web Application Description Language (WADL). Como conseqüência, os serviços ganham uma grande liberdade de evoluir sem ter que se preocupar se os consumidores existentes vão quebrar.

HATEOAS e o acoplamento fraco

Quando estamos desenvolvendo um serviço, devemos abstrair detalhes de implementação dos consumidores, reduzindo assim o acoplamento. Entretanto, não importa o grau de acoplamento fraco, o consumidor deve ter informação suficiente disponível para interagir com o nosso serviço. Precisamos prover alguma maneira para que estes possam consumir nossos serviços e interagir com o protocolo de aplicação suportado. A beleza da hypermedia é que ela nos permite transmitir informações sobre o protocolo de forma declarativa e Just-in-time como parte das representações dos recursos que compõe a aplicação.

Contratos Web são expressados por meio de media-types e links. Aceitando que uma media-type significa que entendemos como processar o formato para interagir com um serviço. Usando as mídias e os links suportados por um serviço, podemos extender um contrato através da WEB em tempo de execução promovendo novos links e transições de estado.

Para interações web computer-to-computer, nós publicamos um protocolo adicionando links a uma representação, de forma muito semelhante a que fazemos com interações web human-to-computer. Para descrever o propósito de um link, adicionamos anotações. Anotações indicam o que o recurso apontado pelo link significa para o recurso atual. Para fazer anotações, podemos usar microformatos ou outras tecnologias de web semântica, ou nos podemos projetar nossos próprios formatos.

Hypermedia formats

Sistemas distribuídos dirigidos para hypermedia (hypermedia-driven) atendem as demandas de seus consumidores de forma similar a que Web atende “usuários humanos”: consumidores precisam “descobrir” e interagir com recursos para que consigam atingir seus objetivos.

Para ilustrar como um formato de representação permite a consumidores “descobrir” e interagir com recursos, consideremos XHTML, uma dos mais populares formatos de representação disponíveis para World Wide Web. XHTML é usada para representar a informação de uma página a para fazer link para outras páginas ou conteúdo. A inclusão de links para outros recursos caracteriza XHTML como um Hypermedia format.

A Web é agnóstica para os formatos utilizados na troca de recursos entre consumidores e serviços, que é uma das razões principais para seu sucesso em diversos domínios. Mas, quando tratamos de hypermedia, nem todos os formatos são iguais.

Apesar do sucesso dos formatos com suporte para hypermedia, as aplicações distribuídas usam formatos como plain XML para integrar sistemas (que não são, nativamente, hypermedia). Embora XML seja fácil de usar como um formato de trocas, e apesar de sua quase onipresença, é totalmente alheio a Web.

Não há nada errado em usar plain xml quando considerada de forma isolada. Afinal, ela transmite o estado atual do recurso de forma boa o suficiente. Mas, por outro lado, falha terrivelmente ao prover qualquer contexto; ou seja, não indica o estado atual no processo negócio, nem como avançar.

O uso de XML simples deixa o consumidor sem um guia – um protocolo – para completar uma transação que tenha sido iniciada. Por não haver qualquer controle hypermedia na representação, o consumidor precisa confiar em informações “fora” do recurso para determiar o que precisaria ser feito em seguida. Da perspectiva de construção de um serviço menos acoplado, essa é uma decisão pobre de design.

Aspectos importantes da implementação do serviço acabam “escapando” para mecanismos como URI templates, fortemente considerados na implementação de clientes, tornando qualquer mudança difícil e arriscada.

Podemos, claro, comunicar o protocolo para os desenvolvedores de aplicações consumidoras usando documentação, ou contratos estáticos como WSDL, WADL ou URI templates, mas…

 

Abstrato demais? Bom, por hoje foi o que deu… Me ajudem, nos comentários a elucidar o conceito.

Smiley piscando

Etiquetado:,
Publicado em: Sem categoria