<?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>DEV Community: Expertos Tech</title>
    <description>The latest articles on DEV Community by Expertos Tech (@expertostech).</description>
    <link>https://dev.to/expertostech</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%2F781393%2F08423940-709a-4461-931e-fe5bb1150e55.png</url>
      <title>DEV Community: Expertos Tech</title>
      <link>https://dev.to/expertostech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/expertostech"/>
    <language>en</language>
    <item>
      <title>O que é gRPC - Como usar os Protocol Buffers | Parte 2</title>
      <dc:creator>Expertos Tech</dc:creator>
      <pubDate>Tue, 26 Apr 2022 16:01:08 +0000</pubDate>
      <link>https://dev.to/expertostech/o-que-e-grpc-como-usar-os-protocol-buffers-parte-2-mk3</link>
      <guid>https://dev.to/expertostech/o-que-e-grpc-como-usar-os-protocol-buffers-parte-2-mk3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Autor:&lt;/strong&gt; Rodrigo G. Tavares&lt;br&gt;
&lt;strong&gt;Veja a Parte 1:&lt;/strong&gt; &lt;a href="https://dev.to/expertostech/o-que-e-grpc-seus-componentes-rpc-e-http2-parte-1-nnm"&gt;O que é gRPC - Seus componentes RPC e HTTP2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/rqXBSbN84lo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Protocol Buffers ou para os íntimos Protobuf, é uma linguagem neutra criada para permitir a integração entre linguagens de programação, também usado como IDL pelo sistema gRPC.&lt;/p&gt;

&lt;p&gt;Veremos nesse artigo o que são os Protocol Buffers, como eles funcionam e como eles se integram com o sistema gRPC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Quando falamos de integração entre linguagens, estamos trazendo o conceito de interoperabilidade, ou seja, a capacidade das aplicações e sistemas se comunicarem de maneira simples e fácil.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são os Protocol Buffers?
&lt;/h2&gt;

&lt;p&gt;É uma linguagem neutra de plataforma neutra, usada para definição de tipos de dados e funções, muito parecido com o formato JSON, porém menor e mais rápido. &lt;/p&gt;

&lt;p&gt;Como vimos no artigo anterior, ele é usado como IDL, linguagem para definição de interfaces, no sistema gRPC.&lt;/p&gt;

&lt;p&gt;Por que eu preciso de uma linguagem neutra?&lt;br&gt;
Uma linguagem neutra é uma linguagem simples, usada pra fazer a definição das interfaces e tipos usada nas integrações entre sistemas.&lt;/p&gt;

&lt;p&gt;A partir dessa interface, cada linguagem que queira fazer uma integração deve interpretar o código escrito na IDL, gerando funções e tipos nos padrões da sua linguagem.&lt;/p&gt;

&lt;p&gt;Essas interfaces geradas são chamadas de stubs e são usadas tanto pelo provedor de serviços, quanto pelo consumidor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frt9v8944fzzv3nekcm9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frt9v8944fzzv3nekcm9x.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O lado provedor usará as interfaces para efetivamente implementar as regras daquele serviço, enquanto o consumidor, como o próprio nome diz, vai usá-las pra consumir, ou seja, acessar os serviços.&lt;br&gt;
E é exatamente esse o papel dos protocol buffers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estrutura dos Protocol Buffers
&lt;/h2&gt;

&lt;p&gt;Precisamos de atenção nos padrões e convenções de formatação do arquivo proto. &lt;/p&gt;

&lt;p&gt;Mas por que isso é importante? &lt;br&gt;
Usar o formato correto faz com que o processo de geração dos stubs siga as convenções de cada linguagem. &lt;br&gt;
Em resumo, seguindo o padrão dos protocol buffers, fará com que o código gerado também esteja no padrão da linguagem de destino.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurações
&lt;/h3&gt;

&lt;p&gt;Ao criar o arquivo protocol buffer, por convenção o nome do arquivo deve ser todo minúsculo com a extensão .proto.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pessoa.proto&lt;/li&gt;
&lt;li&gt;pessoafisica.proto&lt;/li&gt;
&lt;li&gt;pessoajuridica.proto&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Sintaxe
&lt;/h4&gt;

&lt;p&gt;Uma vez criado o arquivo, devemos atribuir a versão da sintaxe, que pode ser: proto2 ou proto3.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Desse ponto em diante focaremos na versão de sintaxe &lt;code&gt;proto3&lt;/code&gt;, que é a versão mais recente, para mais detalhes referente a versão &lt;code&gt;proto2&lt;/code&gt;, há um link para a documentação nas referências do artigo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pacote
&lt;/h4&gt;

&lt;p&gt;Agora precisamos definir o pacote, essa é uma instrução opcional usada pra compor o nome da mensagem, essa configuração deixa o nome único e evitando conflitos com outros tipos de nome semelhante, ou seja, podemos ter tipos de nomes iguais, desde de que estes estejam em pacotes diferentes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;expertostech&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;A instrução package em Java, go e csharp é usada pra compor o código gerado, no caso do csharp o valor é atribuído ao &lt;code&gt;namespace&lt;/code&gt;, já no Go e no Java é atribuído em uma propriedade de mesmo nome.&lt;/p&gt;

&lt;h4&gt;
  
  
  Importação
&lt;/h4&gt;

&lt;p&gt;Depois temos a área de importação, onde você pode fazer referência pra outros tipos, como é o caso da definição de data hora que precisa ser importado. Você também pode importar seus próprios tipos como referência.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"google/protobuf/timestamp.proto"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"endereco.proto"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Opções adicionais
&lt;/h4&gt;

&lt;p&gt;Vamos agora para as configurações específicas de cada linguagem.&lt;/p&gt;

&lt;p&gt;Para o Java, as configurações são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;java_multiple_files&lt;/code&gt;, se verdadeiro, indica que as classes serão geradas em arquivos separados.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;java_outer_classname&lt;/code&gt;, o nome da classe para geração.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_multiple_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_outer_classname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"PessoaProtos"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Se você quiser organizar seus arquivos proto em pacotes diferentes das suas classes, você pode usar as seguintes configurações:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;java_package&lt;/code&gt;, para o Java;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;go_package&lt;/code&gt;, para o Go;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;csharp_namespace&lt;/code&gt;, para o C#.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas três configurações sobrescrevem o valor do pacote, package ou namespace no c#, alterando os valores para geração das classes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"expertostech.tutorial.grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;go_package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"expertostech/tutorial/grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;csharp_namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ExpertosTech.Tutorial.Grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Definição de tipos
&lt;/h3&gt;

&lt;p&gt;Uma curiosidade, é que os tipos nos protocol buffers são chamados de &lt;code&gt;message&lt;/code&gt;, justamente por que esses tipos são usados como "mensagem" de envio e respostas nas suas integrações entre sistemas.&lt;/p&gt;
&lt;h4&gt;
  
  
  Mensagem
&lt;/h4&gt;

&lt;p&gt;Iniciamos a declaração cada tipo com a palavra chave &lt;code&gt;message&lt;/code&gt;, seguido do nome no padrão CamelCase.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&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;É importante saber que podemos declarar várias mensagens em um mesmo arquivo proto.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Usuario&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;h4&gt;
  
  
  Atributos
&lt;/h4&gt;

&lt;p&gt;Agora vamos declarar os atributos da mensagem.&lt;/p&gt;

&lt;p&gt;Cada atributo começa com o tipo, seguido do nome e ao fim um código de identificação único.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;documento_pessoal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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;Esse código deve ser único na mensagem e não no arquivo proto, isso quer dizer que você pode ter vários identificadores de atributo com o número 1, por exemplo, desde que eles estejam em mensagens diferentes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;documento_pessoal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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;Essa identificação deve ser feita a partir do número 1 e pode chegar até 536.870.911, ou (2^29)-1.&lt;/p&gt;

&lt;p&gt;Eu tenho minhas dúvidas se você vai precisar chegar tão longe, mas é importante dizer que os números entre 19.000 à 19.999 são reservados para a identificação dos atributos do framework, isso quer dizer que se você usá-los, a geração dos stubs apresentará erro.&lt;/p&gt;

&lt;p&gt;Nos atributos usamos como convenção de nome, letras minúsculas separando cada palavra com um underscore.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;documento_pessoal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&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;h4&gt;
  
  
  Tipos de dados
&lt;/h4&gt;

&lt;p&gt;Na tabela abaixo podemos ver os principais tipos para declaração de atributos e quais são os seus correspondentes nas principais linguagens. Caso queira ver a lista completa, há um link para a documentação nas referências do artigo.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;.proto Type&lt;/th&gt;
&lt;th&gt;C++ Type&lt;/th&gt;
&lt;th&gt;Java/Kotlin Type&lt;/th&gt;
&lt;th&gt;C# Type&lt;/th&gt;
&lt;th&gt;Go Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;int&lt;/td&gt;
&lt;td&gt;int&lt;/td&gt;
&lt;td&gt;int&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;float64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;double&lt;/td&gt;
&lt;td&gt;double&lt;/td&gt;
&lt;td&gt;double&lt;/td&gt;
&lt;td&gt;double&lt;/td&gt;
&lt;td&gt;float32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;boolean&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Além dos tipos de dados da linguagem, você também pode usar como tipos nos seus atributos suas próprias mensagens, ou seja, você pode por exemplo criar uma mensagem &lt;code&gt;Cidade&lt;/code&gt; e usá-la como referência dentro da mensagem &lt;code&gt;Endereco&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Endereco&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;logradouro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;bairro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Cidade&lt;/span&gt; &lt;span class="na"&gt;cidade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Cidade&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;ddd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&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;É importante ressaltar que caso o tipo utilizado localizado em outro arquivo proto, é necessário importá-lo na seção &lt;code&gt;import&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"endereco.proto"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;documento_pessoal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Endereco&lt;/span&gt; &lt;span class="na"&gt;endereco&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&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;h4&gt;
  
  
  Listas de valores
&lt;/h4&gt;

&lt;p&gt;Um recurso muito utilizado nas integrações são as listas de valores e temos dois tipos de listas nos protocol buffers:&lt;/p&gt;
&lt;h5&gt;
  
  
  Listas simples
&lt;/h5&gt;

&lt;p&gt;Para declarar uma lista usamos a palavra chave &lt;code&gt;repeated&lt;/code&gt;, seguida pelo tipo do campo e o nome da lista.&lt;br&gt;
Por convenção, uma vez que as listas possuem diversos itens, elas sempre são nomeadas no plural.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;repeated&lt;/span&gt; &lt;span class="n"&gt;Endereco&lt;/span&gt; &lt;span class="na"&gt;enderecos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&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;h5&gt;
  
  
  Listas chave e valor
&lt;/h5&gt;

&lt;p&gt;Outra lista que temos disponível é a de chave e valor, chamada de &lt;code&gt;map&lt;/code&gt;, nesse tipo de lista podemos definir um tipo de dado para chave e outro tipo de dado para valor, lembrando que tanto na chave quanto no valor podemos usar tipos da linguagem ou nossos próprios tipos.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;google.protobuf.Timestamp&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="na"&gt;atualizacoes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&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;h4&gt;
  
  
  Enumerações
&lt;/h4&gt;

&lt;p&gt;Fechando os principais tipos da linguagem, também temos um conjunto de valores fixos chamados de &lt;code&gt;enum&lt;/code&gt;.&lt;br&gt;
Os enums têm a estrutura semelhante a de uma mensagem, porém, ao invés de atributos, há uma lista fixa de valores.&lt;/p&gt;

&lt;p&gt;Pra declarar uma enumeração usamos a palavra chave &lt;code&gt;enum&lt;/code&gt; seguida do nome no padrão CamelCase.&lt;br&gt;
Para a lista de valores, usamos as letras todas maiúsculas separando as palavras por um underscore.&lt;/p&gt;

&lt;p&gt;Os itens do &lt;code&gt;enum&lt;/code&gt; também precisam ser numerados, só que diferente dos atributos da mensagem, a lista de valores do enum deve iniciar no número 0.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;TipoPessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;NAO_DEFINIDA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="na"&gt;FISICA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="na"&gt;JURIDICA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&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;h4&gt;
  
  
  Serviços
&lt;/h4&gt;

&lt;p&gt;Fechamos a definição dos tipos, agora precisamos definir nossos serviços e funções.&lt;/p&gt;

&lt;p&gt;Isso é muito simples, usamos a palavra chave &lt;code&gt;service&lt;/code&gt;, seguida do nome do serviço no padrão CamelCase.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;PessoaServico&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;Para declararmos uma função dentro do seu serviço, iniciamos com a palavra chave &lt;code&gt;rpc&lt;/code&gt;, seguida pelo o nome da funcionalidade no padrão CamelCase, o parâmetro de entrada entre parênteses, seguido da palavra chave &lt;code&gt;returns&lt;/code&gt; com a mensagem de retorno da função também entre parênteses.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;PessoaServico&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;PessoaPorDocumento&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&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;Podemos declarar várias funções dentro de um mesmo serviço e obrigatoriamente todas elas precisam de uma mensagem como parâmetro de entrada e uma outra como parâmetro de saída.&lt;/p&gt;

&lt;p&gt;Não podemos ter funções sem entrada ou saída, e os parâmetros devem obrigatoriamente ser mensagens e não tipos simples, como strings, inteiros e etc.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;PessoaServico&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;PessoaPorDocumento&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;PessoaPorNome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&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;Vejamos abaixo o código completo dos protocol buffers usados até aqui como exemplo.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Arquivo: endereco.proto&lt;/em&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;expertostech&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_multiple_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_outer_classname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"EnderecoProtos"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"expertostech.tutorial.grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;go_package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"expertostech/tutorial/grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;csharp_namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ExpertosTech.Tutorial.Grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Endereco&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;logradouro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;bairro&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Cidade&lt;/span&gt; &lt;span class="na"&gt;cidade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Cidade&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;ddd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&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;&lt;em&gt;Arquivo: pessoa.proto&lt;/em&gt;&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;expertostech&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"google/protobuf/timestamp.proto"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"endereco.proto"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_multiple_files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_outer_classname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"PessoaProtos"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;java_package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"expertostech.tutorial.grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;go_package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"expertostech/tutorial/grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;csharp_namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ExpertosTech.Tutorial.Grpc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;PessoaServico&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;PessoaPorDocumento&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;&lt;br&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;PessoaPorNome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pessoa&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;documento_pessoal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="k"&gt;repeated&lt;/span&gt; &lt;span class="n"&gt;Endereco&lt;/span&gt; &lt;span class="na"&gt;enderecos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;google.protobuf.Timestamp&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="na"&gt;atualizacoes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="n"&gt;TipoPessoa&lt;/span&gt; &lt;span class="na"&gt;tipo_pessoa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;TipoPessoa&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="na"&gt;NAO_DEFINIDA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="na"&gt;FISICA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="na"&gt;JURIDICA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Usuario&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;senha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Gerando os stubs com Java&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Para testar a geração veja o projeto completo no Github:&lt;br&gt;
&lt;a href="https://github.com/expertos-tech/protocol-buffer" rel="noopener noreferrer"&gt;github/expertos-tech/protocol-buffer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veja abaixo a estrutura do projeto e arquivo &lt;code&gt;pom.xml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbc38kh04hbo6uj5bushf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbc38kh04hbo6uj5bushf.png" alt="Estrutura do projeto"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;&lt;br&gt;
&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"&lt;a href="http://maven.apache.org/POM/4.0.0" rel="noopener noreferrer"&gt;http://maven.apache.org/POM/4.0.0&lt;/a&gt;"&lt;/span&gt;&lt;br&gt;
         &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"&lt;a href="http://www.w3.org/2001/XMLSchema-instance" rel="noopener noreferrer"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/a&gt;"&lt;/span&gt;&lt;br&gt;
         &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"&lt;a href="http://maven.apache.org/POM/4.0.0" rel="noopener noreferrer"&gt;http://maven.apache.org/POM/4.0.0&lt;/a&gt; &lt;a href="http://maven.apache.org/xsd/maven-4.0.0.xsd" rel="noopener noreferrer"&gt;http://maven.apache.org/xsd/maven-4.0.0.xsd&lt;/a&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;
    &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;groupId&amp;amp;gt;&amp;lt;/span&amp;gt;expertostech&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/groupId&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;stub-gen&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;version&amp;amp;gt;&amp;lt;/span&amp;gt;1.0-SNAPSHOT&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/version&amp;amp;gt;&amp;lt;/span&amp;gt;


&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;properties&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;maven.compiler.source&amp;amp;gt;&amp;lt;/span&amp;gt;17&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/maven.compiler.source&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;maven.compiler.target&amp;amp;gt;&amp;lt;/span&amp;gt;17&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/maven.compiler.target&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/properties&amp;amp;gt;&amp;lt;/span&amp;gt;

&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;dependencies&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;dependency&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;groupId&amp;amp;gt;&amp;lt;/span&amp;gt;io.grpc&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/groupId&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;grpc-stub&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;version&amp;amp;gt;&amp;lt;/span&amp;gt;1.45.1&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/version&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/dependency&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;dependency&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;groupId&amp;amp;gt;&amp;lt;/span&amp;gt;io.grpc&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/groupId&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;grpc-protobuf&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;version&amp;amp;gt;&amp;lt;/span&amp;gt;1.45.1&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/version&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/dependency&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;dependency&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;groupId&amp;amp;gt;&amp;lt;/span&amp;gt;jakarta.annotation&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/groupId&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;jakarta.annotation-api&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;version&amp;amp;gt;&amp;lt;/span&amp;gt;1.3.5&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/version&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;optional&amp;amp;gt;&amp;lt;/span&amp;gt;true&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/optional&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/dependency&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/dependencies&amp;amp;gt;&amp;lt;/span&amp;gt;

&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;build&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;extensions&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;extension&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;groupId&amp;amp;gt;&amp;lt;/span&amp;gt;kr.motd.maven&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/groupId&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;os-maven-plugin&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;version&amp;amp;gt;&amp;lt;/span&amp;gt;1.4.1.Final&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/version&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/extension&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/extensions&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;plugins&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;plugin&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;groupId&amp;amp;gt;&amp;lt;/span&amp;gt;org.xolstice.maven.plugins&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/groupId&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;protobuf-maven-plugin&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/artifactId&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;version&amp;amp;gt;&amp;lt;/span&amp;gt;0.6.1&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/version&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;configuration&amp;amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;protocArtifact&amp;amp;gt;&amp;lt;/span&amp;gt;com.google.protobuf:protoc:3.3.0:exe:${os.detected.classifier}&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/protocArtifact&amp;amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;pluginId&amp;amp;gt;&amp;lt;/span&amp;gt;grpc-java&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/pluginId&amp;amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;pluginArtifact&amp;amp;gt;&amp;lt;/span&amp;gt;io.grpc:protoc-gen-grpc-java:1.4.0:exe:${os.detected.classifier}&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/pluginArtifact&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/configuration&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;executions&amp;amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;execution&amp;amp;gt;&amp;lt;/span&amp;gt;
                    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;goals&amp;amp;gt;&amp;lt;/span&amp;gt;
                        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;goal&amp;amp;gt;&amp;lt;/span&amp;gt;compile&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/goal&amp;amp;gt;&amp;lt;/span&amp;gt;
                        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;goal&amp;amp;gt;&amp;lt;/span&amp;gt;compile-custom&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/goal&amp;amp;gt;&amp;lt;/span&amp;gt;
                    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/goals&amp;amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/execution&amp;amp;gt;&amp;lt;/span&amp;gt;
            &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/executions&amp;amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/plugin&amp;amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/plugins&amp;amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;/build&amp;amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  O que vem a seguir?&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Fechamos a definição dos protocol buffers, que é a parte central do sistema gRPC.&lt;br&gt;
No próximo artigo, última parte dessa série, entraremos na parte prática de tudo que vimos até aqui, a implementação passo a passo de um serviço gRPC com Java, usando os protocol buffers.&lt;/p&gt;

&lt;p&gt;E se você chegou até aqui, deixe o seu gostei no artigo e já aproveita pra seguir o canal ExpertosTech em todas redes sociais:&lt;br&gt;
&lt;a href="https://linktr.ee/expertostech" rel="noopener noreferrer"&gt;https://linktr.ee/expertostech&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Referencias:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/protocol-buffers/docs/overview" rel="noopener noreferrer"&gt;Documentação Prtocol Buffers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>protocolbuffers</category>
      <category>grpc</category>
      <category>protobuf</category>
      <category>rpc</category>
    </item>
    <item>
      <title>Vulnerabilidade do Spring e Java de março de 2022 | SpringShell ou Spring4Shell</title>
      <dc:creator>Expertos Tech</dc:creator>
      <pubDate>Mon, 04 Apr 2022 15:44:23 +0000</pubDate>
      <link>https://dev.to/expertostech/vulnerabilidade-do-spring-e-java-de-marco-de-2022-springshell-ou-spring4shell-557d</link>
      <guid>https://dev.to/expertostech/vulnerabilidade-do-spring-e-java-de-marco-de-2022-springshell-ou-spring4shell-557d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Autor:&lt;/strong&gt; Rodrigo Tavares&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3uteRUREPMM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Afinal de contas, o que é essa vulnerabilidade do Spring Framework com Java, divulgada na última quarta-feira dia 30 de março de 2022?&lt;/p&gt;

&lt;p&gt;Também chamada de SpringShell ou Spring4Shell, a maior dúvida nesse momento é: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Será que a minha aplicação está exposta e correndo risco de ataque"&lt;/li&gt;
&lt;li&gt;"Será que meus dados ou dos meus clientes estão seguros?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Então, pra saber tudo sobre essa vulnerabilidade e principalmente, como corrigir o problema, vem comigo até o final desse artigo que eu vou te mostrar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como foi relatada
&lt;/h2&gt;

&lt;p&gt;Na última quarta-feira, 30 de março, alguns blogs apresentaram alguns prints de tela relatando uma possível vulnerabilidade no Spring Framework, o que eles chamaram de SpringShell. &lt;br&gt;
Em alguns lugares chamavam de Spring4Shell, fazendo uma relação com uma vulnerabilidade parecida encontrada no Log4J recentemente conhecida como Log4JShell.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Print de uma PoC, proof of concept, postada no Twitter no dia 30 de março de 2022 demonstrando a vulnerabilidade&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxv02708luwl529yi7pb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxv02708luwl529yi7pb.png" alt="Print do post no Twitter"&gt;&lt;/a&gt; &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faizlwkrod1qhh4mobinr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faizlwkrod1qhh4mobinr.png" alt="PoC da vulnerabilidade"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Segunda vez, mesmo problema
&lt;/h3&gt;

&lt;p&gt;Um ponto interessante, é que essa mesma vulnerabilidade já havia sido tratada e corrigida em 2010, mas devido a uma nova funcionalidade do Java 9, foi possível explorar a vulnerabilidade de novo, vamos entender isso mais à frente.&lt;/p&gt;
&lt;h3&gt;
  
  
  No que consiste o problema
&lt;/h3&gt;

&lt;p&gt;Para permitir a troca de dados entre cliente e aplicação o Spring converte dados das requisições HTTP em objetos e vice-versa.&lt;/p&gt;

&lt;p&gt;Com o intuito de justamente evitar que um possível invasor tenha controle indevido à aplicação, container ou servidor usando funcionalidades internas desses objetos, o Spring Framework faz um tratamento especial protegendo acessos à objetos como &lt;code&gt;Class&lt;/code&gt;, &lt;code&gt;ClassLoader&lt;/code&gt; e &lt;code&gt;ProtectionDomain&lt;/code&gt;, provavelmente ajustes feitos em 2010, na primeira ocorrência do problema.&lt;/p&gt;

&lt;p&gt;Na atualização do Java 9, houve uma modificação do objeto Class, o que fez com que os tratamentos e validações implementadas pelo Spring Framework não fossem suficientes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Classe CachedIntrospectionResults do Spring Framework, linha 288&lt;/em&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="nc"&gt;PropertyDescriptor&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beanInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPropertyDescriptors&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PropertyDescriptor&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pds&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;beanClass&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
            &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"classLoader"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;  &lt;span class="s"&gt;"protectionDomain"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;())))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Ignore Class.getClassLoader() and getProtectionDomain() methods - nobody needs to bind to those&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como é possível ver nesse trecho de código do Spring Framework, os métodos &lt;code&gt;getClassLoader()&lt;/code&gt; e &lt;code&gt;getProtectionDomain()&lt;/code&gt; não podem ser sobrescritos e ainda há um comentário que dizendo que eles foram ignorados por não haver necessidade de atribuir nada à neles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;// Ignore Class.getClassLoader() and getProtectionDomain() methods - nobody needs to bind to those&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Resumindo, o objetivo da conversão das informações de uma requisição HTTP em objetos ou a serialização destes para texto é única e exclusivamente para troca de POJOs entre a aplicação e os clientes, controles à recursos do Java, servidores, bancos de dados e etc, devem ser explicitamente programados.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que mudou no Java 9
&lt;/h2&gt;

&lt;p&gt;O Java 9 introduziu o método &lt;code&gt;getModule&lt;/code&gt; no objeto &lt;code&gt;Class&lt;/code&gt; e isso permitiu a utilização do método &lt;code&gt;getModule().getClassLoader()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vale dizer que o simples acesso ao &lt;code&gt;ClassLoader&lt;/code&gt; não é por si só uma vulnerabilidade, isso depende da forma que as funcionalidades dele foram implementadas.&lt;/p&gt;

&lt;p&gt;Nesse caso específico, a vulnerabilidade está explorando a implementação da classe, &lt;code&gt;WebAppClassLoaderBase&lt;/code&gt; do Tomcat 9.&lt;/p&gt;

&lt;p&gt;Um ponto importante aqui é que o Java 9 foi lançado em 2017, ou seja, essa vulnerabilidade já vem sendo explorada por 5 anos até 2022, data de publicação desse artigo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passos para reprodução
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Primeiro o invasor usa o ClassLoader das implementações de log pra criar um arquivo JSP malicioso.&lt;/li&gt;
&lt;li&gt;Em seguida, o invasor escreve o código malicioso na página JSP.&lt;/li&gt;
&lt;li&gt;E Pronto, agora é só fazer uma requisição pra página.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esse tipo de acesso é chamado de RCE, Remote Code Execution, podemos dizer que é uma forma mais sofisticada do conhecido SQL Injection.&lt;/p&gt;

&lt;p&gt;Vulnerabilidades como essa são registradas com um CVE, Common Vulnerabilities and Exposures, e aqui falamos de dois:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2022-22965:&lt;/strong&gt; Justamente esse que foi exposto no dia 30 de março; &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2010-1622:&lt;/strong&gt;, solução da exposição do ClassLoader em 2010, antes do lançamento do Java 9.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quem está vulnerável?
&lt;/h2&gt;

&lt;p&gt;Agora que já vimos como funciona a vulnerabilidade vamos ver quem tá exposto.&lt;/p&gt;

&lt;p&gt;Com os detalhes que vimos até agora, acredito você já tenha algumas pistas, segue abaixo todos os itens que você precisa validar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aplicação distribuída no formato war

&lt;ul&gt;
&lt;li&gt;Lembrando que esse não é o formato de distribuição padrão&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Utilizar JDK 9 ou superior&lt;/li&gt;

&lt;li&gt;Ter no seu projeto a dependência spring-webmvc ou spring-webflux
Usar as versões do Spring Framework 5.3.0 até a 5.3.17, 5.2.0 até a 5.2.19 ou versões mais antigas

&lt;ul&gt;
&lt;li&gt;Para Spring Boot são as versões 2.6.5 e 2.5.11 ou versões anteriores&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Usar o Apache Tomcat como container para servlets nas versões 10.0.19, 9.0.61 e 8.5.77 ou versões anteriores.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;E lembrando que a vulnerabilidade não consiste em apenas um deles, você precisa atender todos para estar vulnerável.&lt;/p&gt;

&lt;p&gt;Essa configuração são mais prováveis ao usar o Spring Framework para prover páginas JSP, não há dados da quantidade de sistemas e/ou aplicações afetadas, mas pelos padrões de programação atuais utilizando APIs Rest com páginas SPA ou aplicativos móveis, aparentemente vai afetar mais aplicações legadas.&lt;/p&gt;

&lt;p&gt;A vulnerabilidade requer que haja um diretório para processar as páginas JSP ou para o deploy de arquivos War, pois é justamente onde serão criadas as páginas JSP para acesso como um backdoor.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que fazer para resolver?
&lt;/h2&gt;

&lt;p&gt;Abaixo estão opções para solução da vulnerabilidade, implementando apenas uma das opções abaixo sua aplicação estará segura.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atualizar o Tomcat
&lt;/h3&gt;

&lt;p&gt;Atualizar o Tomcat, com o patch de correção nas versões:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10.0.20;&lt;/li&gt;
&lt;li&gt;9.0.62;&lt;/li&gt;
&lt;li&gt;8.5.78.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;ou qualquer versão superior à essas.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A vantagem de atualizar o Tomcat é justamente centralizar o ponto de correção, resolvendo diretamente o problema em todas as aplicações publicadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atualizar o Spring Framework (ou Spring Boot)
&lt;/h3&gt;

&lt;p&gt;Logo após a divulgação da vulnerabilidade, foi lançado um patch para correção do Spring Framework, sendo assim, basta atualizá-lo para a versão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;5.3.18;&lt;/li&gt;
&lt;li&gt;5.2.20.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;ou qualquer versão superior à essas.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Caso sua aplicação esteja usando &lt;strong&gt;Spring Boot&lt;/strong&gt; atualize para as versões 2.6.6, 2.5.12 ou superior, que estão com suas referências atualizadas para uma das versões do Spring Framework citadas à cima.&lt;/p&gt;

&lt;p&gt;Essa abordagem de atualização já é mais trabalhosa, uma vez que você precisará efetuá-la em todas as aplicações afetadas, então garanta que não esqueceu nenhuma.&lt;/p&gt;

&lt;p&gt;De qualquer forma, mesmo que tenha atualizado o Tomcat, siga com a atualização das dependências do Spring Framework, evitando assim futuros problemas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Downgrade do Java
&lt;/h3&gt;

&lt;p&gt;Não sendo possível atualizar nem o Spring ou nem o Tomcat, outra possibilidade é fazer um downgrade do Java para a versão 8.&lt;/p&gt;

&lt;p&gt;Realmente, pessoalmente é a que menos recomendo, principalmente se sua aplicação foi construída em versões posteriores, pois você pode ter comportamentos não esperados pela sua aplicação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desabilitar acesso à Class
&lt;/h3&gt;

&lt;p&gt;Por fim, você pode desabilitar a atribuição de valores ao objeto &lt;code&gt;Class&lt;/code&gt; com a instrução &lt;code&gt;disallowedFields&lt;/code&gt; para o &lt;code&gt;WebDataBinder&lt;/code&gt; de forma global, como pode ser visto no código abaixo.&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="nd"&gt;@ControllerAdvice&lt;/span&gt;
&lt;span class="nd"&gt;@Order&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Ordered&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LOWEST_PRECEDENCE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BinderControllerAdvice&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@InitBinder&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAllowedFields&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;WebDataBinder&lt;/span&gt; &lt;span class="n"&gt;dataBinder&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
         &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;denylist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]{&lt;/span&gt;&lt;span class="s"&gt;"class.*"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Class.*"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*.class.*"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*.Class.*"&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;
         &lt;span class="n"&gt;dataBinder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDisallowedFields&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;denylist&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aplicar globalmente vai funcionar, mas há uma brecha. &lt;br&gt;
Se qualquer controller implementar seu próprio &lt;code&gt;InitBinder&lt;/code&gt;, ele vai sobrescrever as configurações globais.&lt;/p&gt;

&lt;p&gt;Sendo assim, para seguir essa estratégia de maneira mais segura, você precisa sobrescrever a classe &lt;code&gt;RequestMappingHandlerAdapter&lt;/code&gt; na sua aplicação e atualizar &lt;code&gt;WebDataBinder&lt;/code&gt; ao final de todas as outras inicializações.&lt;/p&gt;

&lt;p&gt;Após a sobrescrição, na sua aplicação Spring Boot você declara um &lt;code&gt;WebMvcRegistrations&lt;/code&gt; bean para Spring MVC ou um &lt;code&gt;WebFluxRegistrations&lt;/code&gt; bean pra Spring WebFlux.&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="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;expertostech&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Arrays&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.SpringApplication&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.autoconfigure.SpringBootApplication&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.ServletRequestDataBinder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.context.request.NativeWebRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.method.annotation.InitBinderDataBinderFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.method.support.InvocableHandlerMethod&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;


&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;


    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CarApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;


    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;WebMvcRegistrations&lt;/span&gt; &lt;span class="nf"&gt;mvcRegistrations&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebMvcRegistrations&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;@Override&lt;/span&gt;
            &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RequestMappingHandlerAdapter&lt;/span&gt; &lt;span class="nf"&gt;getRequestMappingHandlerAdapter&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ExtendedRequestMappingHandlerAdapter&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;};&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;


    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExtendedRequestMappingHandlerAdapter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;RequestMappingHandlerAdapter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;InitBinderDataBinderFactory&lt;/span&gt; &lt;span class="nf"&gt;createDataBinderFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InvocableHandlerMethod&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ServletRequestDataBinderFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getWebBindingInitializer&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                &lt;span class="nd"&gt;@Override&lt;/span&gt;
                &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;ServletRequestDataBinder&lt;/span&gt; &lt;span class="nf"&gt;createBinderInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;NativeWebRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                    &lt;span class="nc"&gt;ServletRequestDataBinder&lt;/span&gt; &lt;span class="n"&gt;binder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createBinderInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;binder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDisallowedFields&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fieldList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emptyList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
                    &lt;span class="n"&gt;fieldList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"class.*"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Class.*"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*.class.*"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*.Class.*"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
                    &lt;span class="n"&gt;binder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDisallowedFields&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toArray&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{}));&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;binder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;};&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E para o Spring MVC sem o Spring Boot, a aplicação pode trocar de &lt;code&gt;@EnableWebMvc&lt;/code&gt; e estender a classe &lt;code&gt;DelegatingWebMvcConfiguration&lt;/code&gt; sobrescrevendo o método &lt;code&gt;createRequestMappingHandlerAdapter&lt;/code&gt;, veja mais detalhes nas referências, configurações avançadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Corri aqui pra trazer esse conteúdo pra vocês o mais rápido possível.&lt;br&gt;
Como vocês podem observar a vulnerabilidade é algo bem específico, e muito improvável colocar em risco aplicações mais novas.&lt;/p&gt;

&lt;p&gt;Como esse é um assunto crítico, importante e sensível, vamos fazer esse conteúdo chegar ao máximo de pessoas possível, então compartilha esse artigo em todas as suas redes sociais, na empresa, seus projetos, com seus clientes, na sua faculdade, com seus professores, e tudo mais.&lt;/p&gt;

&lt;p&gt;Não esquece de seguir o perfil Expertos Tech em todas as redes sociais: &lt;a href="https://linktr.ee/expertostech" rel="noopener noreferrer"&gt;https://linktr.ee/expertostech&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurações Avançadas

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-advanced-java" rel="noopener noreferrer"&gt;https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-advanced-java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Spring Framework

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement" rel="noopener noreferrer"&gt;https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Oracle

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.oracle.com/corporate/features/understanding-java-9-modules.html" rel="noopener noreferrer"&gt;https://www.oracle.com/corporate/features/understanding-java-9-modules.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>spring</category>
      <category>java</category>
      <category>springshell</category>
      <category>spring4shell</category>
    </item>
    <item>
      <title>O que é gRPC - Seus componentes RPC e HTTP2 | Parte 1</title>
      <dc:creator>Expertos Tech</dc:creator>
      <pubDate>Sat, 26 Mar 2022 18:20:27 +0000</pubDate>
      <link>https://dev.to/expertostech/o-que-e-grpc-seus-componentes-rpc-e-http2-parte-1-nnm</link>
      <guid>https://dev.to/expertostech/o-que-e-grpc-seus-componentes-rpc-e-http2-parte-1-nnm</guid>
      <description>&lt;p&gt;&lt;strong&gt;Autor:&lt;/strong&gt; Rodrigo G. Tavares&lt;br&gt;
&lt;strong&gt;Veja a Parte 2:&lt;/strong&gt; &lt;a href="https://dev.to/expertostech/o-que-e-grpc-como-usar-os-protocol-buffers-parte-2-mk3"&gt;O que é gRPC - Como usar os Protocol Buffers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/DyOnW95KO5Y"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Nem tudo são APIs Rest quando falamos de comunicação entre aplicações.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Pensando em reduzir a latência e otimizar a comunicação nas aplicações atuais, o Google criou o sistema gRPC, que é uma implementação do modelo RPC.&lt;br&gt;
No gRPC são usados proto buffers para definição das funcionalidades e a comunicação é feita usando o protocolo HTTP/2.&lt;/p&gt;

&lt;p&gt;Nessa série de artigos veremos todos os detalhes do sistema gRPC: Seus principais componentes, funcionamento, pra que serve, onde e como usar.&lt;/p&gt;

&lt;p&gt;Lembrando que essa aqui é só a primeira parte! &lt;br&gt;
Nessa série além de vermos os detalhes do sistema gRPC, ao fim faremos uma implementação passo a passo, usando gRPC com Java e Spring Boot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Componentes do gRPC
&lt;/h2&gt;

&lt;p&gt;Antes de falarmos de gRPC, precisamos entender dois dos seus principais componentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modelo RPC
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7stv55m7hd14oe1s5iyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7stv55m7hd14oe1s5iyg.png" alt="Funcionamento do RPC"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O RPC, Remote Process Call, como o próprio nome diz, é uma padronização para execução de funcionalidades remotas simulando uma função local, ou seja, isso simplifica muito as integrações entre sistemas.&lt;/p&gt;

&lt;p&gt;Também podemos dizer que na maioria dos casos, o RPC está relacionado à interoperabilidade, isso quer dizer que utilizando uma IDL, Interface Definition Language, podemos especificar uma ou mais funcionalidades detalhando seus tipos, parâmetros e retornos. Isso permite a interpretação dessas instruções por qualquer linguagem de programação.&lt;/p&gt;

&lt;p&gt;Em resumo, o intuito da interoperabilidade é justamente garantir que programas escritos em linguagens de programação distintas possam se comunicar. &lt;/p&gt;

&lt;h4&gt;
  
  
  Padrão CORBA
&lt;/h4&gt;

&lt;p&gt;Uma das mais antigas implementações de RPC é o CORBA, Common Object Request Broker Architecture, que simplificando, consiste na implementação de um módulo chamado ORB, responsável pela comunicação entre clientes e o servidores.&lt;/p&gt;

&lt;h4&gt;
  
  
  Java RMI
&lt;/h4&gt;

&lt;p&gt;Em Java a implementação mais famosa do RPC é o RMI, sigla em inglês para Remote Method Invocation.&lt;/p&gt;

&lt;p&gt;O RMI é a base do famoso Enterprise Java Beans, também conhecido como EJB. &lt;/p&gt;

&lt;p&gt;Sua implementação requer a criação de stubs, que são um conjunto de interfaces que definem as assinaturas dos métodos, parâmetros e retornos.&lt;/p&gt;

&lt;p&gt;Depois de criarmos os stubs, eles são implementados do lado do servidor e distribuídos em uma biblioteca para todos os clientes que invocarão os métodos remotos.&lt;/p&gt;

&lt;p&gt;Uma informação interessante, é que no caso do RMI não há uma IDL para criação dos stubs, eles são escritos na própria linguagem, então isso quer dizer que o foco não é a interoperabilidade e sim a integração entre sistemas distribuídos feitos em Java mesmo.&lt;/p&gt;

&lt;h4&gt;
  
  
  SOAP
&lt;/h4&gt;

&lt;p&gt;Por último e provavelmente a implementação RPC mais conhecida de todas, amplamente utilizada pelas mais diversas linguagens, vamos falar do modelo SOAP, Simple Object Access Protocol.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exemplo de contrato WSDL da Nota Fiscal Eletrônica&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5zq2td9tr8gh4xvddi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5zq2td9tr8gh4xvddi1.png" alt="Exemplo de contrato WSDL da Nota Fiscal Eletrônica"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse modelo usamos o padrão WSDL, Web Services Description Language, que usando instruções por meio de tags e atributos XML, define o contrato do serviço.&lt;br&gt;
Esse contrato é composto pelos tipos de dados, funcionalidades, parâmetros e retornos.&lt;/p&gt;

&lt;p&gt;Para fazer a comunicação com os clientes, é usado protocolo http ou https, e pra acessar os métodos remotos no padrão SOAP, as linguagens fazem a interpretação do contrato WSDL, gerando as interfaces stubs com seus parâmetros para entrada e retorno.&lt;/p&gt;

&lt;p&gt;Uma vez gerados, os stubs são distribuídos para os clientes que queiram invocar as funcionalidades SOAP remotas.&lt;/p&gt;

&lt;p&gt;Agora que entendemos o que é RPC e vimos alguns exemplos, percebam que todas as implementações citadas acima precisam distribuir algum tipo de biblioteca para os clientes.&lt;br&gt;
Guarda essa informação pois vamos precisar dela adiante.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protocolo de comunicação
&lt;/h2&gt;

&lt;p&gt;O gRPC utiliza o protocolo HTTP2 para comunicação, mas para entendermos melhor o motivo pelo qual precisamos dele, veremos os déficits do protocolo HTTP/1.x.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que falta no HTTP/1.x
&lt;/h3&gt;

&lt;p&gt;A definição do protocolo HTTP/1.x é muito simples e essa simplicidade tem um preço, que é redução do desempenho das aplicações.&lt;/p&gt;

&lt;p&gt;A perda de desempenho acontece devido ao protocolo HTTP/1.x não ter compactação de dados e da impossibilidade de priorizar os recursos.&lt;/p&gt;

&lt;p&gt;Normalmente são necessárias várias conexões simultâneas para completar uma requisição que atenda o negócio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokc0u9i7tjkys64dw6r3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokc0u9i7tjkys64dw6r3.png" alt="Crescimento médio das páginas Web em tamanho e número de objetos Jan 1995 – Jul 2014 "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lá no começo isso não fazia diferença nenhuma e o protocolo HTTP/1.x atendia muito bem os seus propósitos, só que hoje, a complexidade das aplicações modernas, precisando de cada vez mais recursos, contornar os problemas de latência é um grande desafio para os desenvolvedores.&lt;/p&gt;

&lt;h3&gt;
  
  
  O Protocolo HTTP2
&lt;/h3&gt;

&lt;p&gt;O protocolo HTTP2 foi criado pelo Google e aprovado no início de 2015 pelo IESG, Grupo de Gestão de Engenharia para Internet, e ele é uma evolução de um protocolo experimental chamado SPDY, também criado pelo Google.&lt;/p&gt;

&lt;p&gt;A primeira grande melhoria do protocolo HTTP2, é o formato dos dados transmitidos. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4467lgpaaiae3z3ojdui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4467lgpaaiae3z3ojdui.png" alt="Diferenças entre os protocolos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enquanto o HTTP/1.x usa o formato de texto simples para comunicação, o protocolo HTTP2 usa um formato binário compactado e isso reduz drasticamente o tamanho da requisição e resposta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comunicação com HTTP2
&lt;/h3&gt;

&lt;p&gt;A comunicação do protocolo HTTP2 é dividida em três partes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stream;&lt;/li&gt;
&lt;li&gt;Mensagem;&lt;/li&gt;
&lt;li&gt;Frame.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  O Stream
&lt;/h3&gt;

&lt;p&gt;Em uma mesma conexão TCP/IP podemos trafegar diversos streams e eles são bidirecionais, ou seja, por eles podemos tanto enviar mensagens como receber sem que seja necessário desconectar. Muito diferente do protocolo HTTP/1.x que só aceita uma requisição e uma resposta por conexão.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Mensagem
&lt;/h3&gt;

&lt;p&gt;É sequência completa de uma requisição e ela transita dentro do stream.&lt;/p&gt;

&lt;p&gt;Como eu já mencionado anteriormente, o protocolo HTTP2 permite a troca de diversas mensagens dentro de um stream e essas mensagens são divididas em frames.&lt;/p&gt;

&lt;h3&gt;
  
  
  Os Frames
&lt;/h3&gt;

&lt;p&gt;Por fim temos os frames, eles são a menor parte e compõem a mensagem. Nos frames temos informações dos cabeçalhos e os dados de requisição e resposta.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recapitulando
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14spza89f5htwdjqsa41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14spza89f5htwdjqsa41.png" alt="Como transitam os dados no HTTP2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma mesma conexão pode transferir vários streams;&lt;/li&gt;
&lt;li&gt;Dentro de cada stream podemos ter várias mensagens; &lt;/li&gt;
&lt;li&gt;Essas mensagens são divididas em frames;&lt;/li&gt;
&lt;li&gt;Os frames transitam os dados efetivos da requisição.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vimos até aqui, quais são os componentes de comunicação do protocolo HTTP2, agora veremos algumas vantagens de desempenho importantes que ele tem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Múltiplas requisições
&lt;/h3&gt;

&lt;p&gt;No protocolo HTTP/1.x, se quisermos fazer solicitações paralelas para minimizar a latência, é necessário efetuar várias conexões simultâneas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e5k9vnqr5544rgzfe1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e5k9vnqr5544rgzfe1b.png" alt="Camada de frame binário do HTTP/2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando usamos os frames binários do protocolo HTTP2, temos o que chamamos de &lt;em&gt;multiplexação completa de requisição e respostas&lt;/em&gt;, que basicamente é a capacidade do protocolo fazer requisições simultâneas, síncronas e assíncronas usando a mesma conexão.&lt;/p&gt;

&lt;p&gt;Além disso também é possível alternar entre as requisições sem bloqueá-las. &lt;br&gt;
Essa requisição elimina o custo de efetuar novas conexões e tudo isso permite a redução da latência geral, otimizando a utilização da rede.&lt;/p&gt;

&lt;h3&gt;
  
  
  Priorização de Stream
&lt;/h3&gt;

&lt;p&gt;Outro avanço importante do protocolo HTTP2 é a possibilidade de alterar a prioridade dos streams.&lt;br&gt;
Esse processo e feito atribuindo um número inteiro entre 1 e 256 a cada stream.&lt;/p&gt;

&lt;p&gt;No protocolo HTTP2, você também pode atribuir uma dependência entre os Streams, ou seja, você poderia por exemplo dizer explicitamente que em uma requisição, a imagem B só será baixada depois da imagem A e isso sem a necessidade de efetuar uma nova conexão.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que vem a seguir?
&lt;/h2&gt;

&lt;p&gt;Pronto, agora que já entendemos os componentes base do sistema gRPC, podemos seguir para o próximo artigo onde veremos o funcionamento do Protocol Buffer, que é a linguagem usada pelo gRPC como IDL pra definição de funcionalidades, parâmetros e retornos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Veja a Parte 2:&lt;/strong&gt; &lt;a href="https://dev.to/expertostech/o-que-e-grpc-como-usar-os-protocol-buffers-parte-2-mk3"&gt;O que é gRPC - Como usar os Protocol Buffers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E se você chegou até aqui, deixe o seu gostei no artigo e já aproveita pra seguir o canal ExpertosTech em todas redes sociais:&lt;br&gt;
&lt;a href="https://linktr.ee/expertostech" rel="noopener noreferrer"&gt;https://linktr.ee/expertostech&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Referencias:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wikipedia

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto" rel="noopener noreferrer"&gt;Chamada de procedimentos remotos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pt.wikipedia.org/wiki/CORBA" rel="noopener noreferrer"&gt;CORBA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Google Developers

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/web/fundamentals/performance/http2" rel="noopener noreferrer"&gt;Introdução a HTTP/2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Receita Federal

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nfe.fazenda.gov.br/portal/webServices.aspx?tipoConteudo=OUC/YVNWZfo=&amp;amp;AspxAutoDetectCookieSupport=1" rel="noopener noreferrer"&gt;Portal da nota fiscal eletrônica&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>grpc</category>
      <category>rpc</category>
      <category>http2</category>
      <category>expertostech</category>
    </item>
  </channel>
</rss>
