<?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: Larissa Tavares</title>
    <description>The latest articles on DEV Community by Larissa Tavares (@larissatavares).</description>
    <link>https://dev.to/larissatavares</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%2F396806%2F8b3001e6-9f0f-427c-8344-ad972cd71bf7.jpeg</url>
      <title>DEV Community: Larissa Tavares</title>
      <link>https://dev.to/larissatavares</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/larissatavares"/>
    <language>en</language>
    <item>
      <title>Conhecendo sobre o protocolo HTTP</title>
      <dc:creator>Larissa Tavares</dc:creator>
      <pubDate>Sat, 14 Sep 2024 13:47:46 +0000</pubDate>
      <link>https://dev.to/larissatavares/conhecendo-sobre-o-protocolo-http-2fje</link>
      <guid>https://dev.to/larissatavares/conhecendo-sobre-o-protocolo-http-2fje</guid>
      <description>&lt;p&gt;Primeiramente precisamos entender que o protocolo HTTP está presente na &lt;strong&gt;camada de aplicação&lt;/strong&gt; do modelo OSI, ela é a única camada que interage diretamente com os dados do usuário&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Modelo OSI (Open System Interconnection) : modelo que oferece um padrão para que diferentes sistemas de computadores possam se comunicar&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  O que é HTTP?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bom, o HTTP é um &lt;strong&gt;protocolo&lt;/strong&gt; ou seja, um conjunto de regras, estabelecido para organizar a maneira como os computadores trocam dados entre si&lt;/li&gt;
&lt;li&gt;HTTP significa &lt;em&gt;Hypertext Transfer Protocol&lt;/em&gt; (Protocolo de transferência de hipertexto). Um conjunto de regras que permite passar com todos os detalhes dados como texto, imagem, vídeos e áudios entre dispositivos&lt;/li&gt;
&lt;li&gt;Suas versões rodam sobre o TCP, e a sua versão mais atual, o HTTP/3 também roda sobre UDP&lt;/li&gt;
&lt;li&gt;Os cabeçalhos de solicitação e resposta são dados em ASCII&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  HTTP e HTTPS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnw9ku1m1a4xsshmf03p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnw9ku1m1a4xsshmf03p.jpg" alt="https" width="760" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Já ouvimos falar que existem esses dois protocolos, mas qual a diferença entre eles?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;O HTTP e o HTTPS recuperam os dados da mesma maneira. A diferença é que o protocolo HTTP quando utiliza um &lt;strong&gt;protocolo de transporte seguro&lt;/strong&gt;, chamado TLS (Transport Layer Security), constitui o que conhecemos como HTTPS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Como funciona?
&lt;/h3&gt;

&lt;p&gt;A comunicação funciona em duas pontas, a partir da solicitação (requisição) no lado do usuário (cliente) para o lado o servidor web, e uma resposta se referindo à ação do servidor &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_hLYchJB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1100/format:webp/0%2Asr8XF4ztxyBBWueS" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_hLYchJB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1100/format:webp/0%2Asr8XF4ztxyBBWueS" alt="Cliente/servidor" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Elementos da requisição
&lt;/h4&gt;

&lt;p&gt;Compostos por:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Método HTTP&lt;/li&gt;
&lt;li&gt;Caminho do recurso a ser buscado&lt;/li&gt;
&lt;li&gt;Versão do protocolo HTTP&lt;/li&gt;
&lt;li&gt;Cabeçalho (&lt;strong&gt;header&lt;/strong&gt;) &lt;/li&gt;
&lt;li&gt;Corpo (&lt;strong&gt;body&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O2CE-YYm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:828/format:webp/1%2AHy0pok8hPBMe6kCJVlU9KQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O2CE-YYm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:828/format:webp/1%2AHy0pok8hPBMe6kCJVlU9KQ.png" alt="Requisicao HTTP" width="656" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Elementos das respostas
&lt;/h4&gt;

&lt;p&gt;Compostos por:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Versão do protocolo HTTP&lt;/li&gt;
&lt;li&gt;Código de status&lt;/li&gt;
&lt;li&gt;Mensagem de status&lt;/li&gt;
&lt;li&gt;Cabeçalho (&lt;strong&gt;header&lt;/strong&gt;) &lt;/li&gt;
&lt;li&gt;Corpo (&lt;strong&gt;body&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4Ceq9nOZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:828/format:webp/1%2Al5K_kfcowwi76zYs8yk3tQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4Ceq9nOZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:828/format:webp/1%2Al5K_kfcowwi76zYs8yk3tQ.png" alt="Resposta HTTP" width="758" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Cabeçalho / Header
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Os cabeçalhos contém informações básicas como tipo de conteúdo, idioma, conjunto de caracteres, entre outros&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Abaixo temos uma lista de alguns dos cabeçalhos de uma requisição HTTP&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accept-Language&lt;/strong&gt; : Determina qual linguagem é entendida pelo cliente e qual a sua região de preferência&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allow&lt;/strong&gt; : Lista quais métodos HTTP são aceitos pelo servidor para o recurso acessado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content-Language&lt;/strong&gt; : É a forma do servidor dizer ao cliente quais linguagens estão disponíveis para o recurso atual&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cookie&lt;/strong&gt; : Contém o valor de um Cookie HTTP e é a forma do navegador enviar esse dado de volta ao servidor a cada requisição&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content-Type&lt;/strong&gt; : Indica qual o tipo de mídia de um recurso&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User-Agent&lt;/strong&gt; : Contém uma string de identificação da aplicação, sistema operacional e distribuidor do software que fez a requisição&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Corpo / Body
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;É a resposta àquela solicitação. No HTTP, pode ser desde um simples texto, a um hipertexto (HTML), um arquivo PDF, uma imagem, JSON, XML etc&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Métodos HTTP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Os métodos indicam ações que a solicitação HTTP espera de um determinado servidor consultado&lt;/li&gt;
&lt;li&gt;Cada método estipula uma operação diferente&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Existem nove métodos HTTP, são eles
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GET&lt;/strong&gt;&lt;br&gt;
Solicita o envio de um recurso específico. Requisições utilizando este método retornam apenas dados&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HEAD&lt;/strong&gt;&lt;br&gt;
Solicita apenas o cabeçalho da mensagem, sem conter o corpo da mensagem&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;POST&lt;/strong&gt;&lt;br&gt;
Submete uma entidade a um recurso específico, geralmente causando uma mudança no estado do recurso. Faz o upload de dados para um servidor&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PUT&lt;/strong&gt;&lt;br&gt;
Substitui a representação atual do destino pela carga de dados da requisição&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;br&gt;
Exclui um recurso específico&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TRACE&lt;/strong&gt;&lt;br&gt;
Serve para depuração, ele instrui o servidor a enviar de volta a solicitação. É útil quando a solicitação não está sendo processada corretamente, e o cliente deseja saber qual solicitação o servidor recebeu&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CONNECT&lt;/strong&gt;&lt;br&gt;
Estabelece uma conexão com o servidor através de um dispositivo intermediário. Exemplo: cache web&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OPTIONS&lt;/strong&gt;&lt;br&gt;
Fornece um meio para que o cliente consulte o servidor e obtenha os métodos e cabeçalhos que podem ser usados&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PATCH&lt;/strong&gt;&lt;br&gt;
Utilizado para aplicar modificações parciais em um recurso&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Códigos de status de resposta HTTP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Toda solicitação obtém uma resposta que contém uma linha de status e as informações adicionais da página&lt;/li&gt;
&lt;li&gt;A linha de status possui um código de três dígitos informando se a solicitação foi atendida, se não e porque não&lt;/li&gt;
&lt;li&gt;O primeiro dígito serve para dividir a resposta em cinco grupos importantes&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Grupos
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Código&lt;/th&gt;
&lt;th&gt;Significado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1xx&lt;/td&gt;
&lt;td&gt;Informação&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2xx&lt;/td&gt;
&lt;td&gt;Sucesso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3xx&lt;/td&gt;
&lt;td&gt;Redirecionamento&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4xx&lt;/td&gt;
&lt;td&gt;Erro do cliente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5xx&lt;/td&gt;
&lt;td&gt;Erro do servidor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Alguns exemplos de códigos de status
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Código&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100 Continue&lt;/td&gt;
&lt;td&gt;Indica que o cliente deve continuar a solicitação ou ignorar a resposta se a solicitação já estiver concluída&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102 Processing&lt;/td&gt;
&lt;td&gt;Indica que o servidor recebeu e está processando a requisição, mas nenhuma resposta está disponível ainda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200 Ok&lt;/td&gt;
&lt;td&gt;Indica que a solicitação foi bem sucedida&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;201 Created&lt;/td&gt;
&lt;td&gt;A requisição foi bem sucedida e um novo recurso foi criado como resultado. Normalmente utilizado após requisições POST ou PUT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;202 Accepted&lt;/td&gt;
&lt;td&gt;A solicitação foi recebida mas ainda não foi atendida, nesse caso não será enviado nenhuma resposta posteriormente de forma assíncrona. É utilizado em casos em que outro processo ou servidor manipula a solicitação&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;300 Multiple Choices&lt;/td&gt;
&lt;td&gt;A solicitação tem mais de uma resposta possível, e o usuário deve escolher um deles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;301 Moved Permanently&lt;/td&gt;
&lt;td&gt;A URL do recurso solicitado foi movido permanentemente, a nova URL é enviada na resposta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;302 Found&lt;/td&gt;
&lt;td&gt;Significa que a URI do recurso foi alterada temporariamente, mas que essa mesma URI deve ser usada para requisições no futuro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400 Bad Request&lt;/td&gt;
&lt;td&gt;O servidor não pode processar a requisição devido a um erro do cliente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;401 Unauthorized&lt;/td&gt;
&lt;td&gt;Significa que o cliente deve se autenticar para obter a resposta desejada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;403 Forbidden&lt;/td&gt;
&lt;td&gt;O cliente não tem direitos de acesso ao conteúdo, diferente do 401, aqui a identidade do cliente é conhecida&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404 Not Found&lt;/td&gt;
&lt;td&gt;Indica que o servidor não pode encontrar o recurso solicitado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;418 I'm a Teapot&lt;/td&gt;
&lt;td&gt;O servidor se recusa a preparar café com um bule de chá&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;429 Too Many Requests&lt;/td&gt;
&lt;td&gt;O cliente enviou muitas requisições em um dado tempo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;500 Internal Server Error&lt;/td&gt;
&lt;td&gt;O servidor encontrou uma condição inesperada que o impediu de atender a solicitação&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;501 Not Implemented&lt;/td&gt;
&lt;td&gt;O servidor não reconhece o método de solicitação e não é capaz de suportá-lo para nenhum recurso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;502 Bad Gateway&lt;/td&gt;
&lt;td&gt;Ao atuar como gateway ou proxy, o servidor recebeu uma resposta inválida de um servidor de entrada que ele acessou ao tentar atender à solicitação&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Versões do HTTP
&lt;/h3&gt;

&lt;h4&gt;
  
  
  HTTP/1.0
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A conexão entre um navegador e um servidor, habitualmente é feita através da conexão TCP&lt;/li&gt;
&lt;li&gt;No HTTP/1.0 depois que a conexão era estabelecida, uma única solicitação era enviada e uma única resposta era devolvida, e a conexão TCP era encerrada&lt;/li&gt;
&lt;li&gt;Porém como as páginas Web continham grandes números de links, imagens e ícones, o estabelecimento de uma única conexão TCP para transportar um único ícone se tornou muito custoso, com isso surgiu o HTTP/1.1&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  HTTP/1.1
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Com essa versão foram admitidas conexões persistentes&lt;/li&gt;
&lt;li&gt;Assim é possível estabelecer uma conexão TCP, enviar uma solicitação e obter uma resposta, e depois enviar solicitações adicionais e receber respostas adicionais&lt;/li&gt;
&lt;li&gt;Também é chamado de &lt;strong&gt;reúso de conexão&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  HTTP/2.0
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Melhorias de desempenhos&lt;/li&gt;
&lt;li&gt;No HTTP/2, uma conexão TCP é estabelecida e muitas solicitações podem ser enviadas e o servidor pode responder a elas em qualquer ordem que desejar&lt;/li&gt;
&lt;li&gt;Através de um mecanismo chamado server push, o HTTP/2 permite que o servidor envie arquivos que ele já sabe serem necessários, mas que o cliente pode não saber inicialmente&lt;/li&gt;
&lt;li&gt;As respostas podem retornar em qualquer ordem&lt;/li&gt;
&lt;li&gt;O HTTP/2 compacta os cabeçalhos e os envia em binário para reduzir o uso da largura de banda e a latência&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  HTTP/3.0
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Sua principal diferença é o protocolo de transporte usado para dar suporte às mensagens HTTP: em vez de depender do TCP, ele depende de uma versão aumentada do UDP chamada QUIC, que conta com o controle de congestionamento do espaço do usuário executado em cima do UDP&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.httpstatus.com.br/" rel="noopener noreferrer"&gt;Códigos de Status HTTP&lt;/a&gt;&lt;br&gt;
&lt;a href="https://books.google.com.br/books/about/Redes_de_Computadores_coedi%C3%A7%C3%A3o_Bookman.html?id=DNFJEAAAQBAJ&amp;amp;source=kp_book_description&amp;amp;redir_esc=y" rel="noopener noreferrer"&gt;TANENBAUM, A.S. Redes de Computadores. 1988.&lt;/a&gt;&lt;br&gt;
&lt;a href="https://madushan-perera.medium.com/diving-into-the-http-protocol-519df10b28e9" rel="noopener noreferrer"&gt;Diving into the HTTP&lt;/a&gt;&lt;/p&gt;

</description>
      <category>http</category>
      <category>programming</category>
    </item>
    <item>
      <title>Conceitos básicos de MongoDB utilizando C#/.NET | Fazendo seu primeiro CRUD</title>
      <dc:creator>Larissa Tavares</dc:creator>
      <pubDate>Mon, 04 Dec 2023 01:45:45 +0000</pubDate>
      <link>https://dev.to/larissatavares/conceitos-basicos-de-mongodb-utilizando-cnet-fazendo-seu-primeiro-crud-4g84</link>
      <guid>https://dev.to/larissatavares/conceitos-basicos-de-mongodb-utilizando-cnet-fazendo-seu-primeiro-crud-4g84</guid>
      <description>&lt;p&gt;O MongoDB é um banco de dados não relacional, também chamado de &lt;strong&gt;NoSQL&lt;/strong&gt;. É orientado a &lt;strong&gt;documentos&lt;/strong&gt;, os quais podem ser descritos com dados no formato chave-valor utilizando o formato &lt;strong&gt;JSON (JavaScript Object Notation)&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Os bancos de dados NoSQL, diferente dos bancos relacionais, não utilizam os esquemas de organização por meio de tabelas, linhas e colunas. E apresentam algumas vantagens como &lt;strong&gt;escalabilidade&lt;/strong&gt;, &lt;strong&gt;flexibilidade&lt;/strong&gt;, &lt;strong&gt;bom desempenho&lt;/strong&gt; e &lt;strong&gt;facilidade para consultas&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Driver MongoDB C#&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Neste exemplo criaremos uma API Web que fará as operações de &lt;em&gt;CRUD (criar, ler, atualizar e deletar)&lt;/em&gt; no banco de dados NoSQL MongoDB. &lt;/p&gt;

&lt;h4&gt;
  
  
  Modelo de configuração
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;[Estação de trabalho] Instalar o MongoDB utilizando Docker:  &lt;a href="https://balta.io/blog/mongodb-docker"&gt;MongoDb Docker&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Código] Adicionar a dependência do pacote NuGet do MongoDB: &lt;a href="https://www.nuget.org/packages/MongoDB.Driver"&gt;MongoDB.Driver&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Código] Inicialmente adicionaremos os &lt;strong&gt;valores de conexão&lt;/strong&gt; do banco de dados no arquivo de configurações denominando &lt;code&gt;appsettings.json&lt;/code&gt;. Passando informações como a &lt;strong&gt;string de conexão&lt;/strong&gt; (&lt;em&gt;ConnectionString&lt;/em&gt;), o banco de dados (&lt;em&gt;DatabaseName&lt;/em&gt;) e a coleção (&lt;em&gt;CollectionName&lt;/em&gt;) que iremos acessar no MongoDB.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  appsettings.json
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"MongoDatabase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"ConnectionString"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"mongodb://localhost:27017"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"DatabaseName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BookStore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"CollectionName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Books"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"Logging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"LogLevel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Information"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Microsoft.AspNetCore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Warning"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"AllowedHosts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;[Código] Agora criaremos uma classe denominada &lt;code&gt;DatabaseSettings&lt;/code&gt; que irá conter os parâmetros &lt;strong&gt;equivalentes&lt;/strong&gt; aos que criamos no &lt;code&gt;appsettings.json&lt;/code&gt;. Esta classe irá &lt;strong&gt;armazenar os valores de propriedade&lt;/strong&gt; do &lt;code&gt;appsettings.json&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseSettings&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ConnectionString&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DatabaseName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CollectionName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="k"&gt;null&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;ul&gt;
&lt;li&gt;[Código] No &lt;code&gt;Program.cs&lt;/code&gt; adicionaremos a linha a seguir. A instância de configuração da seção &lt;code&gt;MongoDatabase&lt;/code&gt; presente no arquivo &lt;code&gt;appsettings.json&lt;/code&gt; é registrada no contêiner de injeção de dependência.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MongoDatabase"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em outras palavras, a propriedade &lt;code&gt;ConnectionString&lt;/code&gt; de um objeto do tipo &lt;code&gt;DatabaseSettings&lt;/code&gt; será populada com a propriedade &lt;code&gt;MongoDatabase:ConnectionString&lt;/code&gt; do &lt;code&gt;appsettings.json&lt;/code&gt;. &lt;/p&gt;




&lt;h4&gt;
  
  
  Modelo de entidade
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;[Código] A seguir criaremos nosso modelo de entidade que utilizaremos em todas as operações do CRUD.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BsonId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;BsonRepresentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BsonType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&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;Id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="nf"&gt;BsonElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;BookName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;!;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Author&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="k"&gt;null&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;Descrição das annotations:&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;[BsonId]&lt;/strong&gt;: Designa a propriedade Id como chave primária.&lt;br&gt;
&lt;strong&gt;[BsonRepresentation(BsonType.ObjectId)]&lt;/strong&gt;: Permite a passagem do parâmetro como tipo &lt;code&gt;string&lt;/code&gt; em vez de uma estrutura &lt;code&gt;ObjectId&lt;/code&gt;. O MongoDB processa a conversão de &lt;code&gt;string&lt;/code&gt; para &lt;code&gt;ObjectId&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;[BsonElement("Name")]&lt;/strong&gt;: O valor &lt;code&gt;Name&lt;/code&gt;do atributo &lt;code&gt;[BsonElement]&lt;/code&gt; representa o nome da propriedade da coleção do MongoDB.&lt;/p&gt;


&lt;h4&gt;
  
  
  Adicionando o serviço de operações CRUD
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;[Código]: Criar uma classe de serviço denominada &lt;code&gt;BooksService&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;      &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BooksService&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IMongoCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_booksCollection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BooksService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bookStoreDatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
               &lt;span class="n"&gt;bookStoreDatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

           &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mongoDatabase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
               &lt;span class="n"&gt;bookStoreDatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

           &lt;span class="n"&gt;_booksCollection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mongoDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
               &lt;span class="n"&gt;bookStoreDatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CollectionName&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;No código acima temos nossa classe &lt;code&gt;BooksService&lt;/code&gt; e seu construtor. Uma instância do &lt;code&gt;DatabaseSettings&lt;/code&gt; é recuperada da injeção de dependência pela injeção do construtor. Utilizamos a interface &lt;code&gt;IOptions&lt;/code&gt; pois já está registrado como &lt;strong&gt;Singleton&lt;/strong&gt; e pode ser injetado em qualquer vida útil do serviço.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Em cenários onde as opções devem ser recalculadas a cada solicitação, podemos utilizar o &lt;code&gt;IOptionsSnapshot&lt;/code&gt;. Sendo este registrado como &lt;strong&gt;Scoped&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esta técnica fornece acesso para os valores de configuração do &lt;code&gt;appsettings.json&lt;/code&gt;, que foi configurado no início deste artigo. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[Código]: Agora no &lt;strong&gt;Program&lt;/strong&gt; adicionaremos a linha subsequente.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BooksService&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;Neste trecho a classe &lt;code&gt;BooksService&lt;/code&gt; é registrada com a injeção de dependência para dar suporte à injeção de construtor nas classes consumidoras. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O tempo de vida &lt;strong&gt;Singleton&lt;/strong&gt; é o mais apropriado pois a classe &lt;code&gt;BooksService&lt;/code&gt; utiliza uma dependência direta de &lt;code&gt;MongoClient&lt;/code&gt; e de acordo com as &lt;strong&gt;diretrizes oficiais do MongoDB&lt;/strong&gt;, recomenda-se armazenar uma instância do &lt;code&gt;MongoClient&lt;/code&gt; com o tipo de vida útil Singleton.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Singleton&lt;/strong&gt; significa que um objeto do serviço é criado e fornecido para todas as requisições. Assim, todas as requisições obtém o mesmo objeto.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Voltando&lt;/strong&gt; à classe &lt;code&gt;BooksService&lt;/code&gt;, utilizamos os seguintes membros do &lt;code&gt;MongoDB.Driver&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;bookStoreDatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mongoDatabase&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;bookStoreDatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;_booksCollection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mongoDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="n"&gt;bookStoreDatabaseSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CollectionName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MongoClient&lt;/strong&gt; lê a instância do servidor para executar operações de banco de dados e espera uma string de conexão como parâmetro.&lt;/p&gt;

&lt;p&gt;Após o &lt;code&gt;MongoClient&lt;/code&gt; se conectar a uma instância do MongoDB, o método &lt;strong&gt;GetDatabase&lt;/strong&gt; é utilizado para acessar um banco de dados.&lt;/p&gt;

&lt;p&gt;Já o método &lt;strong&gt;GetCollection&lt;/strong&gt; é utilizado para acessar uma coleção. Na chamada para o &lt;code&gt;GetCollection&amp;lt;TDocument&amp;gt;(collection)&lt;/code&gt; temos o &lt;code&gt;TDocument&lt;/code&gt; sendo o tipo de objeto armazenado na coleção e o &lt;code&gt;collection&lt;/code&gt; representando o nome da coleção. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[Código]: Adicionaremos os seguintes métodos na nossa classe &lt;code&gt;BooksService&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BooksService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;CreateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertOneAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;UpdateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;updatedBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReplaceOneAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updatedBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;RemoveAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksCollection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeleteOneAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&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;Os seguintes métodos são acessados nesta classe:&lt;br&gt;
&lt;strong&gt;Find&lt;/strong&gt;: retorna todos os documentos na coleção que correspondem aos critérios de pesquisa fornecidos.&lt;br&gt;
&lt;strong&gt;InsertOneAsync&lt;/strong&gt;: insere o objeto fornecido como um novo documento na coleção.&lt;br&gt;
&lt;strong&gt;ReplaceOneAsync&lt;/strong&gt;: substitui o único documento que corresponde aos critérios de pesquisa fornecidos com o objeto fornecido.&lt;br&gt;
&lt;strong&gt;DeleteOneAsync&lt;/strong&gt;: exclui um único documento que corresponde aos critérios de pesquisa fornecidos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Outros métodos que podem ser utilizados estão listados no link &lt;a href="https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/Methods_T_MongoDB_Driver_IMongoCollectionExtensions.htm"&gt;IMongoCollectionExtensions Methods&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h4&gt;
  
  
  Adicionar um &lt;em&gt;controller&lt;/em&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;[Código]: No nosso último passo iremos adicionar um controlador utilizando o seguinte código. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neste trecho temos métodos de ação &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt; e &lt;code&gt;DELETE&lt;/code&gt;, que darão suporte às nossas solicitações.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api/[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BooksController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BooksService&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BooksController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BooksService&lt;/span&gt; &lt;span class="n"&gt;booksService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
         &lt;span class="n"&gt;_booksService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;booksService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id:length(24)}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;

         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;book&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="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;CreatedAtAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;newBook&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="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpPut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id:length(24)}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;updatedBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;

         &lt;span class="n"&gt;updatedBook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

         &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UpdateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updatedBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NoContent&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="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpDelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id:length(24)}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
     &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;

         &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_booksService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoveAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NoContent&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;Após isso, iremos adicionar a chamada do método &lt;code&gt;AddControllers&lt;/code&gt; e para o método &lt;code&gt;MapControllers&lt;/code&gt; no nosso &lt;strong&gt;Program&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddControllers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddJsonOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JsonSerializerOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyNamingPolicy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapControllers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Com a alteração &lt;code&gt;AddJsonOptions&lt;/code&gt; anterior, os nomes de propriedade na resposta JSON serializada da API Web correspondem aos respectivos nomes de propriedade no tipo de objeto.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Ferramentas utilizadas&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pacote Nuget: &lt;a href="https://www.nuget.org/packages/MongoDB.Driver"&gt;MongoDB.Driver&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Linguagem: C# .NET 8.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Código no GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/larissatavares-ads/MongoDBSolutions/tree/main/CrudBasicoMongoDB"&gt;Larissa Tavares - MongoDBSolutions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Com isso finalizamos nossos entendimentos iniciais acerca de MongoDB e sobre como configurá-lo de maneira adequada. Além de termos bastante aparato teórico para entender muito sobre o nosso código. O código final está disponível no GitHub e seu link está disponível acima. Abraços!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.treinaweb.com.br/blog/o-que-e-mongodb"&gt;Treinaweb - O que é MongoDB?&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/pt-br/aspnet/core/tutorials/first-mongo-app?view=aspnetcore-8.0&amp;amp;tabs=visual-studio"&gt;Microsoft Learn - Criar uma API Web com o ASP.NET Core e o MongoDB&lt;/a&gt;&lt;br&gt;
&lt;a href="https://mongodb.github.io/mongo-csharp-driver/2.14/reference/driver/connecting/#re-use"&gt;MongoDB - Connection String&lt;/a&gt;&lt;br&gt;
&lt;a href="https://mongodb.github.io/mongo-java-driver/3.4/driver/tutorials/databases-collections/#:~:text=Once%20you%20have%20a%20MongoClient,store%20data%20for%20that%20database."&gt;MongoDB - Databases and Collections&lt;/a&gt;&lt;br&gt;
&lt;a href="https://mongodb.github.io/mongo-csharp-driver/2.14/apidocs/html/Methods_T_MongoDB_Driver_IMongoCollectionExtensions.htm"&gt;MongoDB - IMongoCollectionExtensions Methods&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Trabalhando com Queues (Filas) no RabbitMQ utilizando C#/.NET</title>
      <dc:creator>Larissa Tavares</dc:creator>
      <pubDate>Wed, 15 Nov 2023 18:33:56 +0000</pubDate>
      <link>https://dev.to/larissatavares/trabalhando-com-queues-filas-no-rabbitmq-utilizando-cnet-3be5</link>
      <guid>https://dev.to/larissatavares/trabalhando-com-queues-filas-no-rabbitmq-utilizando-cnet-3be5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Neste exemplo criaremos uma fila de trabalho responsável por distribuir tarefas demoradas entre seus consumidores. Um consumidor atarefado só irá receber outra mensagem após informar que está livre.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Caso você esteja começando agora com RabbitMQ, sugiro que inicie por este artigo: &lt;a href="https://dev.to/larissatavares/rabbitmq-entendimentos-iniciais-1d55"&gt;Conceitos iniciais sobre RabbitMQ utilizando C#/.NET&lt;/a&gt;&lt;/em&gt;
&lt;/h4&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Despacho Round-Robin&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ao utilizar as filas de tarefas (Task Queues) pode-se facilmente balancear as cargas de trabalho. Se houver muito &lt;strong&gt;acúmulo de trabalho&lt;/strong&gt;, podemos adicionar mais consumidores/trabalhadores e assim melhorar a escalabilidade e garantir a disponibilidade, especialmente em sistemas distribuídos e em cenários onde o processamento de tarefas pode ser demorado.&lt;/p&gt;

&lt;p&gt;Por padrão o RabbitMQ enviará em sequência as mensagens para cada consumidor. Em média &lt;strong&gt;cada consumidor receberá a mesma quantidade de mensagens&lt;/strong&gt;. Esta forma de distribuição de mensagens é denominada &lt;strong&gt;Round-Robin&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Problemática&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Porém&lt;/strong&gt; existe uma problemática em cima desta forma de distribuição de mensagens. Existem cenários em que um consumidor inicia uma tarefa longa e morre com ela, deixando a tarefa &lt;strong&gt;parcialmente concluída&lt;/strong&gt;. Neste cenário, após enviar a mensagem para um consumidor, o RabbitMQ a marca imediatamente para &lt;strong&gt;exclusão&lt;/strong&gt;, fazendo com que a &lt;strong&gt;mensagem seja perdida&lt;/strong&gt; caso o consumidor/trabalhador seja encerrado.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Confirmação de mensagem&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Para que uma mensagem não seja perdida, o RabbitMQ possui um reconhecimento/confirmação de mensagens. Caso um consumidor morra sem enviar uma confirmação, o RabbitMQ irá entender que a mensagem não foi totalmente processada e a &lt;strong&gt;colocará novamente na fila&lt;/strong&gt;. Se houver outro consumidor online, ele enviará rapidamente ao outro consumidor. Dessa forma, &lt;strong&gt;nenhuma mensagem é perdida&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para confirmar manualmente as mensagens, desativaremos o parâmetro de reconhecimento automático &lt;code&gt;AutoAck&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Colocaremos o &lt;code&gt;AutoAck&lt;/code&gt; como falso no &lt;code&gt;BasicConsume&lt;/code&gt; e adicionaremos uma chamada para o &lt;code&gt;BasicAck&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  CONSUMIDOR:
&lt;/h4&gt;

&lt;pre&gt;
...
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                };

channel.BasicConsume(queue: "payments-queue",
                     autoAck: false,
                     consumer: consumer);
&lt;/pre&gt;

&lt;p&gt;Com isso podemos garantir que mesmo encerrando um nó de trabalho enquanto ele processava uma mensagem, nada será perdido.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Durabilidade da mensagem&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Mesmo garantindo que a mensagem não seja perdida caso o consumidor morra, se &lt;strong&gt;o servidor do RabbitMQ morrer as tarefas ainda serão perdidas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para que o RabbitMQ não esqueça as filas e mensagens caso seja parado, devemos &lt;strong&gt;marcar as filas e mensagens como duráveis&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Precisamos ter certeza que a fila sobreviverá à reinicialização do nó do RabbitMQ. Para isso a declaramos como &lt;strong&gt;durável&lt;/strong&gt; (&lt;em&gt;durable: true&lt;/em&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  CONSUMIDOR E PRODUTOR:
&lt;/h4&gt;

&lt;pre&gt;
...
channel.QueueDeclare(queue: "payments-queue",
                     durable: true,
                     exclusive: false,
                     autoDelete: false,
                     arguments: null);
&lt;/pre&gt;

&lt;p&gt;Esta alteração deverá ser realizada tanto no consumidor (&lt;em&gt;consumer&lt;/em&gt;) quanto no produtor (&lt;em&gt;producer&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Agora, precisamos marcar nossas mensagens como &lt;strong&gt;persistentes&lt;/strong&gt;. No produtor, após o &lt;em&gt;GetBytes&lt;/em&gt; iremos definir o &lt;code&gt;IBasicProperties.Persistent&lt;/code&gt; como &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  PRODUTOR:
&lt;/h4&gt;

&lt;pre&gt;
...
 var body = Encoding.UTF8.GetBytes(message);

 var properties = channel.CreateBasicProperties();
 properties.Persistent = true;
&lt;/pre&gt;

&lt;p&gt;Marcar as mensagens como persistentes irá informar ao RabbitMQ para gravar as mensagens no disco.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Despacho justo&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Em uma situação onde temos &lt;strong&gt;dois consumidores&lt;/strong&gt;, quando todas as mensagens pares são pesadas e as mensagens ímpares são leves, consequentemente &lt;strong&gt;um deles estará constantemente ocupado e o outro estará mais livre&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Normalmente o RabbitMQ não saberá sobre essa situação e continuará enviando as mensagens de forma uniforme. Ele não analisa o número de mensagens não confirmadas de um consumidor, ele apenas despacha a mensagem &lt;em&gt;n&lt;/em&gt; para o conumidor &lt;em&gt;n&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Para corrigir este problema, devemos utilizar do método &lt;code&gt;BasicQos&lt;/code&gt;(Qos = Quality of Service) com a configuração &lt;code&gt;prefetchCount = 1&lt;/code&gt;. Isso diz ao RabbitMQ para &lt;strong&gt;não fornecer mais de uma mensagem para um consumidor sem que antes este informe que já processou e confirmou a anterior&lt;/strong&gt;. Ao invés disso ele irá despachar a mensagem para o próximo consumidor que esteja disponível.&lt;/p&gt;

&lt;p&gt;Iremos adicionar o &lt;code&gt;BasicQos&lt;/code&gt; após o &lt;code&gt;QueueDeclare&lt;/code&gt; no código do consumidor.&lt;/p&gt;

&lt;h4&gt;
  
  
  CONSUMIDOR:
&lt;/h4&gt;

&lt;pre&gt;
...
channel.QueueDeclare(queue: "payments-queue",
                     durable: true,
                     exclusive: false,
                     autoDelete: false,
                     arguments: null);

channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
&lt;/pre&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Na prática:&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  - SEM AS CONFIGURAÇÕES
&lt;/h4&gt;

&lt;p&gt;Na imagem seguinte temos os consoles de &lt;strong&gt;um produtor e de dois consumidores&lt;/strong&gt;, sendo que o código &lt;strong&gt;não está com nenhuma das configurações abordadas neste artigo&lt;/strong&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%2Fdku1sk95brfm4rd2c4v8.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%2Fdku1sk95brfm4rd2c4v8.png" alt="Imagem 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem, podemos ver que o produtor envia sequencialmente as mensagens para os consumidores, que as recebem de forma uniforme, sendo que o &lt;strong&gt;consumidor 1 está recebendo as mensagens ímpares&lt;/strong&gt; e o &lt;strong&gt;consumidor 2 as mensagens pares&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Neste cenário o &lt;strong&gt;consumidor 1 está com bastante disponibilidade&lt;/strong&gt; e o &lt;strong&gt;consumidor 2 está bastante atarefado&lt;/strong&gt;, logo vemos que o consumidor 2 está ainda na mensagem 36 e processando a 38, com dezenas de mensagens na sua fila aguardando para serem processadas. Enquanto que o consumidor 1 está equivalente com o produtor, sempre processando a última mensagem enviada.&lt;/p&gt;

&lt;h5&gt;
  
  
  - COM AS CONFIGURAÇÕES
&lt;/h5&gt;

&lt;p&gt;A próxima imagem tem o mesmo consoles do produtor e dos consumidores, porém agora com todas as configurações abordadas neste artigo. Sendo elas o &lt;code&gt;AutoAck&lt;/code&gt;, &lt;code&gt;durable: true&lt;/code&gt; e &lt;code&gt;BasicQos&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%2F6yiywsf36g512wga98ov.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%2F6yiywsf36g512wga98ov.png" alt="Imagem 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste cenário o consumidor 2 não está mais consumindo somente as mensagens pares, assim como o consumidor 1 não está mais consumindo somente as ímpares. &lt;/p&gt;

&lt;p&gt;Os dois estão informando ao RabbitMQ quando estão disponíveis para consumir a próxima mensagem. E assim &lt;strong&gt;o RabbitMQ encaminha de forma equilibrada as mensagens para cada consumidor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vemos que o consumidor 2 continua atarefado, porém &lt;strong&gt;agora ele só recebe uma nova mensagem após processar a anterior&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Ferramentas utilizadas&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pacote Nuget: &lt;a href="https://www.nuget.org/packages/RabbitMQ.Client" rel="noopener noreferrer"&gt;RabbitMQ.Client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Linguagem: C# .NET 6.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Código no GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/larissatavares-ads/RabbitMQ-Solutions/tree/main/AppDelivery" rel="noopener noreferrer"&gt;Larissa Tavares - RabbitMQSolutions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Assim finalizamos nossos entendimentos acerca das &lt;code&gt;queues&lt;/code&gt; e como podemos configurá-las de forma a manter a disponibilidade e persistência de nossas mensagens, de forma a não sobrecarregar nossos consumidores. O código final está disponível no GitHub e seu link está disponível acima.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html" rel="noopener noreferrer"&gt;RabbitMQ - Work Queues using the .NET Client&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.rabbitmq.com/consumer-prefetch.html" rel="noopener noreferrer"&gt;RabbitMQ - Consumer Prefetch&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursos recomendados&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://cursos.alura.com.br/course/microsservicos-pratica-mensageria-rabbitmq" rel="noopener noreferrer"&gt;Alura - Microsserviços na prática: mensageria com RabbitMQ&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rabbitmq</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Conceitos iniciais sobre RabbitMQ utilizando C#/.NET</title>
      <dc:creator>Larissa Tavares</dc:creator>
      <pubDate>Sat, 21 Oct 2023 23:04:47 +0000</pubDate>
      <link>https://dev.to/larissatavares/rabbitmq-entendimentos-iniciais-1d55</link>
      <guid>https://dev.to/larissatavares/rabbitmq-entendimentos-iniciais-1d55</guid>
      <description>&lt;p&gt;O RabbitMQ é um &lt;strong&gt;message broker&lt;/strong&gt;, pois aceita e encaminha mensagens. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Um message broker é um software que possibilita que aplicativos, sistemas e serviços se comuniquem e troquem informações.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Alguns termos a se compreender&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Produtor (&lt;em&gt;Producer&lt;/em&gt;): É um programa que envia mensagens.&lt;/li&gt;
&lt;li&gt;Consumidor (&lt;em&gt;Consumer&lt;/em&gt;): É um programa que espera por mensagens.&lt;/li&gt;
&lt;li&gt;Fila (&lt;em&gt;Queue&lt;/em&gt;): É a caixa postal do RabbitMQ. É um local de armazenamento, que recebe uma mensagem de uma central de troca e as envia aos consumidores.&lt;/li&gt;
&lt;li&gt;Troca (&lt;em&gt;Exchange&lt;/em&gt;): É quem recebe as mensagens do produtor e determina para onde elas devem ser encaminhadas.&lt;/li&gt;
&lt;li&gt;Vinculação (&lt;em&gt;Binding&lt;/em&gt;): É o relacionamento entre uma &lt;em&gt;exchange&lt;/em&gt; e uma &lt;em&gt;queue&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Protocolos de comunicação&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;São responsáveis pela operação do message broker e de como será feito o envio e recebimento de mensagens entre os clientes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;AMQP (&lt;em&gt;Advanced Messaging Queue Protocol&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O modelo AMQP tem a seguinte proposta: Um produtor publica mensagens em uma &lt;em&gt;exchange&lt;/em&gt;, que distribui cópias dessas mensagens para &lt;em&gt;queues&lt;/em&gt; utilizando as regras denominadas &lt;em&gt;bindings&lt;/em&gt;. Em seguida o broker entrega as mensagens aos consumidores inscritos na fila.&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%2F1me26asexy5b5taaij96.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%2F1me26asexy5b5taaij96.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MQTT (&lt;em&gt;Message Queue Telemetry Transport&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É um protocolo para troca de mensagens em ambientes onde existe alguma restrição de hardware, como pouca memória disponível, por exemplo, ou uma limitação de banda. Enfatiza mensagens leves de publicação/assinatura, direcionado a clientes em dispositivos restritos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;STOMP (&lt;em&gt;Simple (or Streaming) Text Oriented Message Protocol&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É um protocolo baseado em texto, construído para trabalhar com middlewares orientados à mensagem. Possui uma estrutura similar ao AMQP, com cabeçalho, propriedades e corpo da mensagem, porém não lida com tópicos ou filas. Ele usa uma semântica de string de destino.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistência no RabbitMQ&lt;/strong&gt;&lt;br&gt;
No RabbitMQ existem dois tipos de fila: as duráveis e as não duráveis. As filas duráveis fazem com que as mensagens permaneçam no disco, enquanto uma fila não durável permanece apenas na memória. Portanto, após a reinicialização do servidor as mensagens nas filas duráveis ficam disponíveis, enquanto as mensagens nas filas não duráveis são perdidas. &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Client .NET/C#&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Neste exemplo será criado um &lt;em&gt;produtor&lt;/em&gt; que envia uma mensagem e um &lt;em&gt;consumidor&lt;/em&gt; que recebe as mensagens e as imprime no console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passos&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;[Estação de trabalho] Instalar o RabbitMQ: &lt;a href="https://www.rabbitmq.com/download.html" rel="noopener noreferrer"&gt;Downloading and Installing RabbitMQ&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Código] Adicionar a dependência do pacote NuGet do RabbitMQ: &lt;a href="https://www.nuget.org/packages/RabbitMQ.Client" rel="noopener noreferrer"&gt;RabbitMQ .NET Client&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Código] Criar uma conexão com o servidor. Esta conexão será usada tanto para o produtor quanto para o consumidor.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PRODUTOR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[Código] Declarar uma fila para enviar a mensagem com &lt;code&gt;QueueDeclare&lt;/code&gt; e publicar uma mensagem na fila com &lt;code&gt;BasicPublish&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Text;
using RabbitMQ.Client;

var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.QueueDeclare(queue: "hello",
                     durable: false,
                     exclusive: false,
                     autoDelete: false,
                     arguments: null);

const string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);

channel.BasicPublish(exchange: string.Empty,
                     routingKey: "hello",
                     basicProperties: null,
                     body: body);
Console.WriteLine($" [x] Sent {message}");

Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CONSUMIDOR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[Código] Declarar a fila da qual será consumida as mensagens com &lt;code&gt;QueueDeclare&lt;/code&gt;, adicionar uma manipulador de eventos denominado &lt;code&gt;EventingBasicConsumer&lt;/code&gt; e consumir a mensagem com &lt;code&gt;BasicConsume&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.QueueDeclare(queue: "hello",
                     durable: false,
                     exclusive: false,
                     autoDelete: false,
                     arguments: null);

Console.WriteLine(" [*] Waiting for messages.");

var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =&amp;gt;
{
    var body = ea.Body.ToArray();
    var message = Encoding.UTF8.GetString(body);
    Console.WriteLine($" [x] Received {message}");
};
channel.BasicConsume(queue: "hello",
                     autoAck: true,
                     consumer: consumer);

Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ferramentas utilizadas&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pacote Nuget: &lt;a href="https://www.nuget.org/packages/RabbitMQ.Client" rel="noopener noreferrer"&gt;RabbitMQ.Client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Linguagem: C# .NET 6.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Código no GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/larissatavares-ads/RabbitMQ-Solutions/tree/main/RabbitMQClient" rel="noopener noreferrer"&gt;Larissa Tavares - RabbitMQClient&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Com isso finalizamos nossos entendimentos iniciais acerca do RabbitMQ. Para aqueles que estão começando agora no ramo da mensageria este post lhe dá um direcionamento inicial. Abaixo seguem as referências de artigos utilizados e cursos recomendados.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html" rel="noopener noreferrer"&gt;RabbitMQ - "Olá Mundo" usando o cliente .NET/C#&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.rabbitmq.com/tutorials/amqp-concepts.html" rel="noopener noreferrer"&gt;RabbitMQ - Modelo AMQP 0-9-1 explicado&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.infoworld.com/article/3200210/how-to-work-with-rabbitmq-in-c.html" rel="noopener noreferrer"&gt;InfoWorld - How to work with RabbitMQ in C#&lt;/a&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/pt/compare/the-difference-between-rabbitmq-and-kafka/#:~:text=Um%20agente%20do%20RabbitMQ%20permite,e%20as%20envia%20aos%20consumidores" rel="noopener noreferrer"&gt;AWS - Abordagem arquitetônica do RabbitMQ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursos recomendados&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://cursos.alura.com.br/course/microsservicos-pratica-mensageria-rabbitmq" rel="noopener noreferrer"&gt;Alura - Microsserviços na prática: mensageria com RabbitMQ&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rabbitmq</category>
      <category>broker</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
