{"id":875,"date":"2016-06-13T06:05:14","date_gmt":"2016-06-13T09:05:14","guid":{"rendered":"https:\/\/www.erudio.com.br\/blog\/?p=875"},"modified":"2022-12-21T11:28:07","modified_gmt":"2022-12-21T14:28:07","slug":"o-que-e-hateoas","status":"publish","type":"post","link":"https:\/\/www.erudio.com.br\/blog\/o-que-e-hateoas\/","title":{"rendered":"Entendendo HATEOAS"},"content":{"rendered":"<p><a href=\"http:\/\/en.wikipedia.org\/wiki\/HATEOAS\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>HATEOAS<\/strong> (Hypermedia as the Engine of Application State)<\/a> \u00e9 uma constraint arquitetural de aplica\u00e7\u00f5es REST. Uma <strong>API HATEOAS<\/strong> prov\u00ea informa\u00e7\u00f5es que permite navegar entre seus endpoints de forma din\u00e2mica visto que inclui links junto \u00e0s respostas. Esta capacidade a difere de sistemas baseados em <strong>SOA<\/strong> e interfaces dirigidas por <strong>WSDL<\/strong>(pronuncia-se u\u00edsdou). Com <strong>SOA<\/strong>, servidores e clientes usualmente devem acessar uma especifica\u00e7\u00e3o fixa que pode ser acessada em outro lugar na <strong>API<\/strong>, ou em um website, ou as vezes distribu\u00eddo por email.<\/p>\n<p><strong>Nota<\/strong>: <em>Pronunciar <strong>HATEOAS <\/strong>n\u00e3o \u00e9 f\u00e1cil e pode variar bastante. Algumas pessoas pronunciam algo como &#8220;<strong>riteos<\/strong>&#8220;, outros como &#8220;<strong>reitos<\/strong>&#8221; ou como &#8220;<strong>reid\u00f4s<\/strong>&#8220;. Alguns podem se referir a esse conceito arquitetural por <strong>hypermedia-driven system<\/strong> \u2013 algo como sistema dirigido por hiperm\u00eddia.<\/em><\/p>\n<p><strong>Exemplos<\/strong><\/p>\n<p>O c\u00f3digo a seguir representa um objeto <em>Cliente<\/em>.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\nclass Cliente {\n\tString nome;\n}\n<\/pre>\n<p>Uma representa\u00e7\u00e3o <strong>JSON<\/strong> tradicional seria algo como:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{\n\t&quot;nome&quot; : &quot;Leandro&quot;\n}\n<\/pre>\n<p>Os dados do <em>Cliente<\/em> est\u00e3o l\u00e1, mas os dados n\u00e3o cont\u00e9m nada de relevante sobre suas conex\u00f5es. Uma representa\u00e7\u00e3o baseada em <strong>HATEOAS<\/strong> deve ser similar ao <strong>JSON<\/strong> abaixo:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{\n   &quot;nome&quot;:&quot;Leandro&quot;,\n   &quot;links&quot;:[\n      {\n         &quot;rel&quot;:&quot;self&quot;,\n         &quot;href&quot;:&quot;http:\/\/localhost:8080\/Cliente\/1&quot;\n      }\n   ]\n}\n<\/pre>\n<p>A resposta n\u00e3o cont\u00e9m somente o nome de uma pessoa, mas inclui uma URL com o endere\u00e7o de onde as informa\u00e7\u00f5es dessa pessoa podem ser localizadas.<\/p>\n<ul>\n<li><em><strong>rel<\/strong><\/em> significa relacionamento. No nosso caso o link autoreferencia a pessoa. Sistemas mais complexos incluem outros tipos de relacionamentos. Por exemplo, uma ordem de compra pode ter um relacionamento com cliente&#8221;rel&#8221;:&#8221;Cliente&#8221; vinculando a ordem ao Cliente.<\/li>\n<li><em><strong>href<\/strong><\/em> \u00e9 uma URL completa que define um \u00fanico recurso.<\/li>\n<\/ul>\n<p><strong>Nota<\/strong>:<br \/>\n<em>Apesar de meus exemplos serem em <strong>JSON<\/strong>, <strong>XML<\/strong> tamb\u00e9m \u00e9 aceito como um formato de resposta padr\u00e3o. <strong>HATEOAS<\/strong> n\u00e3o imp\u00f5e a exig\u00eancia \u00e0 um formato em espec\u00edfico. O seu foco \u00e9 prover links que possibilite navegar entre os recursos de uma <strong>API<\/strong>.<\/em><\/p>\n<p>Apesar de nossos exemplos serem bem simples \u00e9 poss\u00edvel construir rela\u00e7\u00f5es mais complexas. O <strong>HATEOAS<\/strong>, facilita aos desenvolvedores, de aplica\u00e7\u00f5es cliente, acessar os recursos de uma <strong>API<\/strong> sem precisar definir uma especifica\u00e7\u00e3o, criar um documento externo ou uma wiki para isso.<br \/>\nObserve o <strong>JSON<\/strong> abaixo:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{\n   &quot;conteudo&quot;:[\n      {\n         &quot;preco&quot;:499.00,\n         &quot;descricao&quot;:&quot;HD Seagate 2TB&quot;,\n         &quot;nome&quot;:&quot;HD S2TB&quot;,\n         &quot;links&quot;:[\n            {\n               &quot;rel&quot;:&quot;self&quot;,\n               &quot;href&quot;:&quot;http:\/\/localhost:8080\/produto\/1&quot;\n            }\n         ],\n         &quot;atributos&quot;:{\n            &quot;conector&quot;:&quot;SATA&quot;\n         }\n      },\n      {\n         &quot;preco&quot;:49.00,\n         &quot;descricao&quot;:&quot;Mouse \u00d3ptico Dell&quot;,\n         &quot;nome&quot;:&quot; Mouse&quot;,\n         &quot;links&quot;:[\n            {\n               &quot;rel&quot;:&quot;self&quot;,\n               &quot;href&quot;:&quot;http:\/\/localhost:8080\/produto\/3&quot;\n            }\n         ],\n         &quot;atributos&quot;:{\n            &quot;conector&quot;:&quot;wireless&quot;\n         }\n      }\n   ],\n   &quot;links&quot;:[\n      {\n         &quot;rel&quot;:&quot;produto.consulta&quot;,\n         &quot;href&quot;:&quot;http:\/\/localhost:8080\/produto\/consulta&quot;\n      }\n   ]\n}\n<\/pre>\n<p>N\u00e3o apenas os itens e seus precos mostrados, mas tamb\u00e9m uma URL para cada recurso, fornecendo informa\u00e7\u00f5es claras sobre como acessar cada recurso. De acordo com <a href=\"http:\/\/martinfowler.com\/articles\/richardsonMaturityModel.html\" target=\"_blank\" rel=\"noopener noreferrer\">o modelo de maturidade de Richardson<\/a>, <strong>HATEOAS<\/strong> \u00e9 considerado o ultimo n\u00edvel do <strong>REST<\/strong>. Isto significa que em uma aplica\u00e7\u00e3o <strong>HATEOAS<\/strong> presume-se que os verbos padr\u00e3o de uma aplica\u00e7\u00e3o <strong>REST<\/strong> como <strong>GET<\/strong>, <strong>POST<\/strong>, <strong>PUT<\/strong> e <strong>DELETE<\/strong> tamb\u00e9m s\u00e3o adotados. Sendo que cada um deles, como \u00e9 mostrado acima, prov\u00ea ao cliente os links necess\u00e1rios ao acesso \u00e0 uma informa\u00e7\u00e3o.<\/p>\n<p>\u00c9 isso a\u00ed continuem ligados no blog e em breve teremos uma postagem bem m\u00e3o na massa com HATEOAS e o nosso velho conhecido Spring Boot. Bons estudos \ud83d\ude09<\/p>\n<h2>Treinamentos relacionados com este post<\/h2>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_rest_spring_java\" target=\"_blank\" rel=\"noopener\"><\/p>\n<p><img decoding=\"async\" style=\"max-width: 100%;\" title=\"REST API's RESTFul do 0 \u00e0  AWS com Spring Boot 3, Java e Docker\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/07-rest-spring-java.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_rest_asp_net\" target=\"_blank\" rel=\"noopener\"><\/p>\n<p><img decoding=\"async\" style=\"max-width: 100%;\" title=\"REST API's RESTFul do 0 \u00e0 Azure com ASP.NET Core 5 e Docker\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/01-rest-asp.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_rest_spring_kotlin\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"REST API's RESTFul do 0 \u00e0 AWS com Spring Boot 3, Kotlin e Docker\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/18-rest-spring-kotlin.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_microservices_java\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Microservices do 0 com Spring Cloud, Spring Boot e Docker\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/14-microservices-java.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_microservices-dotnet\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Arquitetura de Microsservi\u00e7os do 0 com ASP.NET, .NET 6 e C#\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/15-microservices-dotnet.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_ms_kotlin\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Microsservi\u00e7os do 0 com Spring Cloud, Kotlin e Docker\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/22-ms-kotlin.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_docker\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Docker do 0 \u00e0 Maestria: Cont\u00eaineres Desmistificados mais 3 B\u00d4NUS\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/09-docker.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_docker_para_aws\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Docker para Amazon AWS Implante Apps Java e .NET com Travis CI\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/10-docker-to-aws.png\"><br \/>\n<\/a><\/p>\n<p><a href=\"https:\/\/pub.erudio.com.br\/kr\/blog_kotlin\" target=\"_blank\" rel=\"noopener\"><br \/>\n        <img decoding=\"async\" style=\"max-width: 100%;\" title=\"Kotlin para DEVs Java: Aprenda a Linguagem Padr\u00e3o do Android\" src=\"https:\/\/raw.githubusercontent.com\/leandrocgsi\/blog-images\/main\/20-kotlin.png\"><br \/>\n<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>HATEOAS (Hypermedia as the Engine of Application State) \u00e9 uma constraint arquitetural de aplica\u00e7\u00f5es REST. Uma API HATEOAS prov\u00ea informa\u00e7\u00f5es que permite navegar entre seus endpoints de forma din\u00e2mica visto que inclui links junto \u00e0s respostas. Esta capacidade a difere de sistemas baseados em SOA e interfaces dirigidas por WSDL(pronuncia-se u\u00edsdou). Com SOA, servidores e [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[11,40,96,120],"tags":[132,166,221,247],"_links":{"self":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts\/875"}],"collection":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/comments?post=875"}],"version-history":[{"count":10,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts\/875\/revisions"}],"predecessor-version":[{"id":1518,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/posts\/875\/revisions\/1518"}],"wp:attachment":[{"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/media?parent=875"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/categories?post=875"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.erudio.com.br\/blog\/wp-json\/wp\/v2\/tags?post=875"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}