<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Juan Cassiano</title>
    <description>The latest articles on Forem by Juan Cassiano (@juancassiano).</description>
    <link>https://forem.com/juancassiano</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F820746%2F69e7a42d-bf80-431e-817f-841797bbbd98.png</url>
      <title>Forem: Juan Cassiano</title>
      <link>https://forem.com/juancassiano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/juancassiano"/>
    <language>en</language>
    <item>
      <title>Modelo de Maturidade Richardson</title>
      <dc:creator>Juan Cassiano</dc:creator>
      <pubDate>Wed, 07 Jun 2023 11:43:50 +0000</pubDate>
      <link>https://forem.com/juancassiano/modelo-de-maturidade-richardson-5139</link>
      <guid>https://forem.com/juancassiano/modelo-de-maturidade-richardson-5139</guid>
      <description>&lt;p&gt;É muito comum ver APIs baseadas em arquitetura rest, mas seja por falta de conhecimento ou praticidade, não seguem à risca todas as restrições obrigatórias. A partir disso, temos um mapeamento, feito por Leonard Richardson, chamado &lt;strong&gt;Modelo de Maturidade de Richardson.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nível 0 → Plain Old XML (POX). Nesse nível, o protocolo HTTP é utilizado apenas como transporte de dados, sem a utilização correta dos verbos e status. Geralmente, há apenas um único endpoint. Apesar do nome XML, também é possível utilizar JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;salvarCliente&lt;/span&gt; 
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Cliente&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Manoel da Silva&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Cliente&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse nível, apenas um verbo é utilizado como tipo de operação: o POST. Todas as URLs criadas para obter dados, atualizar dados, inserir e deletar são chamadas utilizando o POST. Outro ponto interessante nesse nível é que há apenas uma única URL para acesso à API. Portanto, caso seja feita uma requisição para obter todos os usuários de um aplicativo, teríamos o seguinte exemplo:&lt;/p&gt;

&lt;p&gt;Da mesma forma, caso a requisição realizada para essa API seja para inserir um novo cliente, a URL utilizada seria a mesma, alterando alguns parâmetros. No desenvolvimento, é responsabilidade do programador garantir que os processos requisitados sejam corretamente manipulados. Por exemplo, a URL para inserir usuários seria:&lt;/p&gt;

&lt;p&gt;O problema de uma API nesse nível é que, para operações simples, é necessário criar muita documentação, pois além da falta de clareza sobre a estrutura e suas relações, os comandos são personalizados na URL.&lt;/p&gt;

&lt;p&gt;Um outro problema constantemente encontrado, é a manipulação incorreta dos códigos de resposta do HTTP. Códigos e mensagens de erros são frequentemente manipuladas nas mensagens geradas pela aplicação, o que impede que elementos de gateway e proxy trabalhem de forma adequada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;buscarCliente&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="nx"&gt;OK&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;buscarCliente&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;status&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;CLIENTE NÃO ENCONTRADO&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;status&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;codigo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;404&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;codigo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;buscarCliente&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nivel 1 → As requisições são feitas para URIs que identificam recursos, porém, os verbos e códigos de status não são utilizados corretamente. O corpo e a resposta também são semelhantes. O tipo de procedimento ainda é definido no corpo.&lt;/p&gt;

&lt;p&gt;Nesse nível, ainda é utilizado apenas um tipo de operação: o &lt;strong&gt;POST&lt;/strong&gt;. Também é importante garantir que, nesse nível, os nomes dos recursos estejam no plural, sem letras maiúsculas e utilizando hífens para separação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;clientes&lt;/span&gt; 
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Cliente&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Manoel da Silva&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Cliente&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nível 2 → Introduz o uso de verbos de acordo com a semântica e o protocolo HTTP. Os códigos são utilizados corretamente. Esse é o nível da maioria das aplicações do mercado. O formato do payload (XML/JSON) não interfere no nível.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cliente&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Cliente&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Manoel da Silva&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Cliente&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma, a API fica muito mais legível para manutenção, reduzindo seu custo e tornando-a mais fácil de ser consumida. Já se sabe, por exemplo, que ao fazer um GET é esperado o retorno de dados, e isso ajuda inclusive na performance da transferência de dados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="nx"&gt;Created&lt;/span&gt;
 &lt;span class="nx"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cliente&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nível 3 → HATEOAS (Hypertext as the engine of application state). Indica quais são as ações possíveis após uma requisição, juntamente com as URIs correspondentes. A ideia é ajudar os consumidores da API a descobrirem as funcionalidades e o fluxo da aplicação. A API retorna os links interligando o recurso com outros (ou até mesmo com ele mesmo), e existem especificações de como implementar os links com JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;cliente&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="nx"&gt;OK&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Cliente&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Manoel da Silva&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"deletar"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/cliente/1"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"notificar"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/cliente/1/notificacao"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;Cliente&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Analisando todos os níveis de maturidade existentes e aplicando todas as práticas para atingi-los, é garantido que, ao construir uma API no nível 3 de maturidade, ela estará organizada, com os endpoints fáceis de serem compreendidos, recursos fáceis de serem encontrados, escalabilidade garantida e uma autodocumentação para seus recursos. Isso facilitará a vida dos usuários que irão consumi-la e dos desenvolvedores que a manterão.&lt;/p&gt;

&lt;p&gt;A implementação do HATEOAS na API traz diversos benefícios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Descoberta dinâmica de recursos: Com o HATEOAS, um cliente da API não precisa ter conhecimento prévio de todos os endpoints e recursos disponíveis. Em vez disso, ele pode começar a partir de um ponto de entrada conhecido (por exemplo, a URL raiz da API) e, a partir da resposta recebida, descobrir os recursos disponíveis e os links relacionados a eles. Isso permite uma experiência mais flexível e adaptável, uma vez que as alterações na API não exigem modificações nos clientes existentes.&lt;/li&gt;
&lt;li&gt;Navegação simplificada: Os links fornecidos pela API permitem que os clientes naveguem facilmente entre os recursos relacionados, sem a necessidade de construir manualmente as URLs correspondentes. Por exemplo, um cliente pode obter um recurso "Cliente" e, a partir dos links fornecidos, navegar para a página de detalhes desse cliente, sua lista de pedidos ou qualquer outro recurso relacionado. Isso simplifica a interação com a API e reduz a carga cognitiva do desenvolvedor.&lt;/li&gt;
&lt;li&gt;Evolução da API: Com o HATEOAS, a API pode evoluir e adicionar novos recursos sem interromper os clientes existentes. Se um novo recurso é introduzido e vinculado a partir das respostas da API, os clientes que entendem o padrão HATEOAS podem descobri-lo e começar a usá-lo. Isso promove uma arquitetura mais flexível e extensível, onde os clientes podem se adaptar a mudanças na API de forma dinâmica.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Exemplo: Suponha que uma API de e-commerce esteja retornando a seguinte resposta JSON para um recurso "Produto":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Camiseta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preco&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;29.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;links&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;self&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/produtos/123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pedidos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/produtos/123/pedidos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;avaliacoes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/produtos/123/avaliacoes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo, os links são fornecidos no campo "links". O link "self" aponta para o próprio recurso "Produto" e os links "pedidos" e "avaliacoes" apontam para recursos relacionados. Um cliente que recebe essa resposta pode utilizar os links para navegar para esses recursos relacionados sem a necessidade de construir manualmente as URLs.&lt;/p&gt;

&lt;p&gt;Portanto, o HATEOAS promove uma abordagem mais dinâmica e exploratória da API, permitindo que os clientes descubram recursos e interajam com eles de forma mais flexível e orientada por hipertexto.&lt;/p&gt;

&lt;p&gt;É importante destacar que a adoção do HATEOAS pode adicionar complexidade à implementação da API e pode não ser necessário ou adequado para todos os casos de uso. Nem todos os projetos precisam ou se beneficiam de todos os níveis de maturidade. Portanto, é fundamental avaliar cuidadosamente as necessidades e metas do projeto antes de decidir em qual nível se concentrar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://martinfowler.com/articles/richardsonMaturityModel.html"&gt;Richardson Maturity Model&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc2616"&gt;RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc7231"&gt;RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/RESTful-Web-APIs-Services-Changing/dp/1449358063"&gt;RESTful Web APIs: Services for a Changing World&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com.br/REST-Practice-Jim-Webber/dp/0596805829"&gt;REST in Practice: Hypermedia and Systems Architecture&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Idempotência em Requisições HTTP</title>
      <dc:creator>Juan Cassiano</dc:creator>
      <pubDate>Mon, 29 May 2023 23:39:13 +0000</pubDate>
      <link>https://forem.com/juancassiano/idempotencia-2chn</link>
      <guid>https://forem.com/juancassiano/idempotencia-2chn</guid>
      <description>&lt;p&gt;A noção de idempotência vem da matemática. Multiplicar um número por zero é uma&lt;br&gt;
operação idempotente. 5 × 0 é zero, mas 5 × 0 × 0 também é zero. Depois de multiplicar um&lt;br&gt;
número por zero, você pode continuar multiplicando-o por zero indefinidamente e obter o mesmo resultado: 0.&lt;/p&gt;

&lt;p&gt;A idempotência é uma propriedade importante de algumas operações HTTP que garante que a &lt;strong&gt;mesma operação pode ser executada várias vezes sem alterar o resultado final ou causar efeitos colaterais indesejados, independente do número de vezes que é chamada&lt;/strong&gt;, isso é importante em situações em que uma operação pode ser executada várias vezes, como em caso de falha de rede ou retry automático de uma operação não concluída.&lt;/p&gt;

&lt;p&gt;Safe Methods:&lt;/p&gt;

&lt;p&gt;Os métodos de solicitação são considerados "seguros" se sua semântica definida for essencialmente somente leitura, ou seja, o &lt;strong&gt;cliente não solicita e não espera qualquer mudança de estado no servidor de origem como resultado de aplicar um método seguro a um recurso de destino&lt;/strong&gt;. Da mesma forma, razoável não se espera que o uso de um método seguro cause qualquer dano, perda de propriedade ou carga incomum no servidor de origem.&lt;/p&gt;

&lt;p&gt;Exemplos de métodos seguros:&lt;/p&gt;

&lt;p&gt;GET → É usado para obter informações sobre um recurso em um servidor. Quando um cliente faz uma solicitação GET, ele espera receber informações sobre o recurso solicitado, mas não espera que a solicitação cause qualquer mudança de estado no servidor. Além disso, é razoável esperar que o uso do método GET não cause nenhum dano, perda de propriedade ou carga incomum no servidor de origem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
&lt;span class="nl"&gt;URL:&lt;/span&gt; &lt;span class="nl"&gt;https:&lt;/span&gt;&lt;span class="c1"&gt;//api.exemplo.com/usuarios/123&lt;/span&gt;
&lt;span class="nl"&gt;Método:&lt;/span&gt; &lt;span class="no"&gt;GET&lt;/span&gt;

&lt;span class="nc"&gt;Status&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="nl"&gt;Resposta:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="no"&gt;OK&lt;/span&gt;
&lt;span class="nc"&gt;Conteúdo&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt; &lt;span class="n"&gt;da&lt;/span&gt; &lt;span class="nl"&gt;Resposta:&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;"nome"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"João Silva"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"joao.silva@exemplo.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;"idade"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;"cidade"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Rio de Janeiro"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HEAD → É usado para obter apenas os cabeçalhos de uma resposta HTTP, permitindo que o cliente verifique informações como o código de status, os cabeçalhos de resposta e a data da última modificação de um recurso. Ex: Um cliente pode enviar uma solicitação HEAD para um recurso de imagem para verificar seu tamanho, tipo de conteúdo e data da última modificação, sem receber o próprio conteúdo da imagem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="no"&gt;HEAD&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;downloads&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;video1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mpeg&lt;/span&gt; &lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q9Qe6QVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27er8wr64a1zx5u96ffp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q9Qe6QVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27er8wr64a1zx5u96ffp.png" alt="Image description" width="468" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OPTIONS →É usado para obter informações sobre as opções de comunicação disponíveis para um determinado recurso ou servidor. Ele retorna os métodos HTTP suportados pelo servidor, cabeçalhos permitidos, entre outras informações relevantes. Ex: Um cliente pode enviar uma solicitação OPTIONS para um servidor de API REST para descobrir quais métodos são permitidos para um determinado recurso, como GET, POST, PUT ou DELETE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="no"&gt;OPTIONS&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;php&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MQmSZMwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9ixxiv6u5a9qyrtmwxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MQmSZMwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9ixxiv6u5a9qyrtmwxz.png" alt="Image description" width="447" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outros métodos idempotêntes:&lt;/p&gt;

&lt;p&gt;DELETE → Obviamente não é um método seguro (Safe Method), porém enviar uma solicitação DELETE é muito diferente de não enviar uma solicitação DELETE. Mas o método DELETE tem outra propriedade muito importante: Ele é idempotente.&lt;br&gt;
Depois de excluir um recurso, ele desaparece. O estado do recurso mudou permanentemente. Você pode enviar outra solicitação DELETE e você pode obter um erro 404, mas o estado do recurso é exatamente como era após o primeiro pedido. O recurso ainda está desaparecido. Isso é idempotência. &lt;strong&gt;Enviar uma solicitação duas vezes tem o mesmo efeito no estado do recurso que enviá-la uma vez.&lt;/strong&gt; A idempotência é um recurso útil, porque a Internet não é uma rede confiável. Suponha você envia uma solicitação DELETE e sua conexão atinge o tempo limite. Você nunca obteve uma resposta, então você não sabe se o DELETE passou. Você pode simplesmente enviar essa solicitação DELETE novamente e continue tentando até obter uma resposta. Nada extra acontecerá se um DELETE passa duas vezes em vez de uma vez.  HTTP DELETE efetivamente multiplica um recurso por zero. Multiplicar por 1 é uma operação segura, da mesma forma que o HTTP GET deve ser seguro. Você pode multiplique um número por 1 durante todo o dia e nada mudará. Toda operação segura é também idempotente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nl"&gt;URL:&lt;/span&gt; &lt;span class="nl"&gt;https:&lt;/span&gt;&lt;span class="c1"&gt;//api.exemplo.com/usuarios/123&lt;/span&gt;
&lt;span class="nl"&gt;Método:&lt;/span&gt; &lt;span class="no"&gt;DELETE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PUT → PUT é idempotente, assim como DELETE. Se você enviar a mesma solicitação PUT 10 vezes, o resultado é o mesmo como se você tivesse enviado apenas uma vez. O cliente também pode usar PUT para criar um novo recurso, se souber a URL onde o novo recurso deve viver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nl"&gt;URL:&lt;/span&gt; &lt;span class="nl"&gt;https:&lt;/span&gt;&lt;span class="c1"&gt;//api.example.com/usuarios/123&lt;/span&gt;
&lt;span class="nl"&gt;Método:&lt;/span&gt; &lt;span class="no"&gt;PUT&lt;/span&gt;
&lt;span class="nc"&gt;Conteúdo&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt; &lt;span class="n"&gt;da&lt;/span&gt; &lt;span class="nl"&gt;solicitação:&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"nome"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"johndoe@example.com"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;"idade"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe que PUT é uma operação idempotente mesmo quando você o usa para criar um novo recurso. Se enviar essa solicitação PUT cinco vezes, ela não será criada cinco postagens com o mesmo texto (da mesma forma que cinco solicitações POST podem).&lt;/p&gt;

&lt;p&gt;Como a definição de seguro, a propriedade idempotente só se aplica a o que foi solicitado pelo usuário. Um servidor é livre para registrar cada um separadamente, reter um histórico de controle de revisão ou implementar outros efeitos colaterais não idempotentes para cada solicitação idempotente.&lt;/p&gt;

&lt;p&gt;Métodos idempotentes são diferenciados porque a requisição pode ser repetida automaticamente se ocorrer uma falha de comunicação antes do cliente ser capaz de ler a resposta do servidor.&lt;/p&gt;

&lt;p&gt;Para garantir que as operações na API sejam idempotentes, é importante que os recursos e endpoints sejam projetados de maneira apropriada, por exemplo, com o uso de identificadores únicos de recursos, como IDs, e o gerenciamento de transações e commits adequados. Isso ajuda a garantir que as operações possam ser executadas várias vezes sem causar problemas indesejados, como a criação de recursos duplicados ou inconsistências de dados.&lt;/p&gt;

&lt;p&gt;E Quanto ao método POST e PATCH?&lt;/p&gt;

&lt;p&gt;O método POST é &lt;strong&gt;não idempotente&lt;/strong&gt;, pois cada chamada cria um novo recurso com um identificador único. Se um cliente enviar várias solicitações POST com os mesmos dados, serão criados vários recursos diferentes no servidor.&lt;/p&gt;

&lt;p&gt;O método POST é &lt;strong&gt;não seguro,&lt;/strong&gt; pois cria um novo recurso no servidor. A criação desse recurso pode ter efeitos colaterais, como enviar notificações, acionar processos de negócios, registrar informações no servidor, entre outros.&lt;/p&gt;

&lt;p&gt;O método PATCH é usado para fazer atualizações parciais em um recurso existente. Em vez de substituir completamente o recurso, o PATCH permite que apenas as alterações específicas sejam aplicadas. No entanto, o método PATCH &lt;strong&gt;não é idempotente nem seguro.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nl"&gt;URL:&lt;/span&gt; &lt;span class="nl"&gt;https:&lt;/span&gt;&lt;span class="c1"&gt;//api.exemplo.com/usuarios/123&lt;/span&gt;
&lt;span class="nl"&gt;Método:&lt;/span&gt; &lt;span class="no"&gt;PATCH&lt;/span&gt;
&lt;span class="nc"&gt;Conteúdo&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt; &lt;span class="n"&gt;da&lt;/span&gt; &lt;span class="nl"&gt;solicitação:&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s"&gt;"idade"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo, a solicitação PATCH é usada para adicionar um campo "idade" a um usuário existente. Se o campo "idade" já estiver presente, a chamada PATCH adicionará um novo valor ao campo. Cada chamada PATCH subsequente com o mesmo conteúdo JSON resultará em alterações adicionais no campo "age" do recurso.&lt;/p&gt;

&lt;p&gt;Um método não idempotente é aquele em que a execução repetida da mesma operação pode ter efeitos diferentes no servidor. Cada chamada adicional a um método não idempotente pode resultar em alterações de estado ou efeitos colaterais diferentes. Portanto, a mesma solicitação enviada várias vezes pode levar a resultados diferentes.&lt;/p&gt;

&lt;p&gt;Um método não seguro é aquele que pode causar alterações no estado do servidor ou ter efeitos colaterais indesejados. Enquanto um método seguro é apenas leitura e não deve causar alterações, um método não seguro pode alterar o estado do servidor ou executar ações que afetam o ambiente.&lt;/p&gt;

&lt;p&gt;Portanto, métodos não idempotentes e não seguros, como POST e PATCH, podem ter efeitos diferentes em cada chamada adicional e podem causar alterações no estado do servidor ou efeitos colaterais indesejados.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Método HTTP&lt;/th&gt;
&lt;th&gt;IDEMPOTÊNCIA&lt;/th&gt;
&lt;th&gt;MÉTODO SEGURO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;SIM&lt;/td&gt;
&lt;td&gt;SIM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HEAD&lt;/td&gt;
&lt;td&gt;SIM&lt;/td&gt;
&lt;td&gt;SIM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;td&gt;SIM&lt;/td&gt;
&lt;td&gt;NÃO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;SIM&lt;/td&gt;
&lt;td&gt;NÃO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;NÃO&lt;/td&gt;
&lt;td&gt;NÃO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PATCH&lt;/td&gt;
&lt;td&gt;NÃO&lt;/td&gt;
&lt;td&gt;NÃO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Documentação: RFC7231 - Seção 4.2.2&lt;/p&gt;

&lt;p&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc7231#autoid-31"&gt;RFC ft-ietf-httpbis-p2-semantics: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Livro:&lt;/p&gt;

&lt;p&gt;Amundsen, Mike Richardson, Leonard Ruby, Sam - RESTful Web APIs-O'Reilly Media (2015)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/RESTful-Web-APIs-Services-Changing/dp/1449358063"&gt;RESTful Web APIs: Services for a Changing World&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rest</category>
      <category>java</category>
      <category>api</category>
      <category>http</category>
    </item>
  </channel>
</rss>
