<?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: Beatriz813</title>
    <description>The latest articles on DEV Community by Beatriz813 (@beatriz813).</description>
    <link>https://dev.to/beatriz813</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%2F252061%2Fb80f2a3d-f152-437b-af5d-25586a159e1c.jpg</url>
      <title>DEV Community: Beatriz813</title>
      <link>https://dev.to/beatriz813</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/beatriz813"/>
    <language>en</language>
    <item>
      <title>Utilização do RabbitMQ para cenários de roteamento complexo.</title>
      <dc:creator>Beatriz813</dc:creator>
      <pubDate>Sun, 01 Oct 2023 12:20:32 +0000</pubDate>
      <link>https://dev.to/beatriz813/utilizacao-do-rabbitmq-para-cenarios-de-roteamento-complexo-2m98</link>
      <guid>https://dev.to/beatriz813/utilizacao-do-rabbitmq-para-cenarios-de-roteamento-complexo-2m98</guid>
      <description>&lt;p&gt;Ao ler a documentação ou posts que falam sobre o caso de uso do RabbitMQ, sempre lemos que ele é uma ótima opção para cenários de roteamento de mensagem, mas por que ele é a melhor opção?&lt;/p&gt;

&lt;p&gt;Este fato se dá pelos artifícios de roteamento que o Rabbit oferece, que são as exchanges e os bindings. As exchanges são entidades para onde as mensagens são enviadas e então roteadas para uma fila de acordo com as regras especificadas nos bindings (vinculação entre a exchange e a fila) dessas exchanges. Dessa forma ele se torna a ferramenta mais adequada para o roteamento de mensagens, porque assim essa lógica de direcionamento é retirada da aplicação e é atribuída para o Rabbit.&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%2F1i3euxzg0i2ttbk2ezia.jpg" 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%2F1i3euxzg0i2ttbk2ezia.jpg" alt="Figura 1 — Utilização de exchange do tipo headers"&gt;&lt;/a&gt;&lt;em&gt;Figura 1 — Utilização de exchange do tipo headers&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A figura acima descreve o seguinte exemplo: dado um sistema de abertura de chamados, um cliente pode abrir um chamado relacionado a uma categoria de problema — pagamento, pedido ou técnico.&lt;br&gt;
Porém, as regras de roteamento para cada fila acontece da seguinte forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;De acordo com a categoria do problema (pagamento, pedido ou técnico).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se a equipe de pedidos tiver menos de três agentes disponíveis, as mensagens de problemas de pedidos devem ser encaminhadas para a equipe de suporte técnico. Se a equipe de suporte de pagamentos tiver menos de dois agentes disponíveis, as mensagens de problemas de pagamento devem ser encaminhadas para a equipe de suporte técnico.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para este cenário poderia ser usado outro broker, como o Apache Kafka por exemplo, mas essa decisão traria essa complexidade de roteamento para dentro da aplicação. Optando pelo RabbitMQ a aplicação só terá a responsabilidade de informar para a exchange a categoria do problema e a quantidade de funcionários disponíveis em cada setor. E assim a exchange se encarregará da distribuição das mensagens de acordo com as regras configuradas nos bindings.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Kubernetes - Variáveis de ambiente</title>
      <dc:creator>Beatriz813</dc:creator>
      <pubDate>Sat, 24 Sep 2022 20:44:50 +0000</pubDate>
      <link>https://dev.to/beatriz813/kubernetes-variaveis-de-ambiente-19j0</link>
      <guid>https://dev.to/beatriz813/kubernetes-variaveis-de-ambiente-19j0</guid>
      <description>&lt;p&gt;Declarando as variáveis diretamente no aquivo yml do Pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: db-noticias
  labels:
    app: db-noticias
spec:
  containers:
    - name: db-noticias-container
      image: aluracursos/mysql-db:1
      ports:
        - containerPort: 3306
      env:
        - name: "MYSQL_ROOT_PASSWORD"
          value: "q1w2e3r4"
        - name: "MYSQL_DATABASE"
          value: "empresa"
        - name: "MYSQL_PASSWORD"
          value: "q1w2e3r4"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criando um serviço de configMap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: ConfigMap
metadata:
  name: db-configmap
data:
  MYSQL_ROOT_PASSWORD: q1w2e3r4
  MYSQL_DATABASE: empresa
  MYSQL_PASSWORD: q1w2e3r4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Primeira forma de vincular o pod com as variáveis do configMap:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: db-noticias
  labels:
    app: db-noticias
spec:
  containers:
    - name: db-noticias-container
      image: aluracursos/mysql-db:1
      ports:
        - containerPort: 3306
      env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: db-configmap
              key: MYSQL_ROOT_PASSWORD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Segunda forma de vincular o pod com as variáveis do configMap, copiando todas as variáveis definidas no configMap:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: db-noticias
  labels:
    app: db-noticias
spec:
  containers:
    - name: db-noticias-container
      image: aluracursos/mysql-db:1
      ports:
        - containerPort: 3306
      envFrom:
        - configMapRef:
            name: db-configmap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Aplicando Sessões em Asp.Net Core</title>
      <dc:creator>Beatriz813</dc:creator>
      <pubDate>Sun, 06 Mar 2022 04:48:48 +0000</pubDate>
      <link>https://dev.to/beatriz813/aplicando-sessoes-em-aspnet-core-ekm</link>
      <guid>https://dev.to/beatriz813/aplicando-sessoes-em-aspnet-core-ekm</guid>
      <description>&lt;h2&gt;
  
  
  O que são sessões?
&lt;/h2&gt;

&lt;p&gt;Tendo em vista duas aplicações Cliente e Servidor que se comunicam através do protocolo HTTP e sabendo que este não mantém estado, a utilização de sessões são uma forma de armazenar os dados voláteis sobre o acesso de um usuário.&lt;/p&gt;

&lt;p&gt;Uma sessão é criada para um navegador, cada uma é identificada por um id de sessão que é mandado para o front que o armazena em um cookie e o utiliza para enviar a cada requisição que faz para o back, desta forma a aplicação do lado servidor é capaz de recuperar os dados da sessão.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como utilizar sessões no Asp.Net Core
&lt;/h2&gt;

&lt;p&gt;Quando criamos um projeto de API ou MVC com asp.net core temos acesso à propriedade HttpContext que guarda todas as informações sobre o acesso que está sendo feito como dados sobre: Session, Request, Response entre outros.&lt;/p&gt;

&lt;p&gt;Porém para persistir dados na Session é preciso habilitar a sua aplicação para que guarde sessão através do uso de cache distribuído e utilizando a DI e o middleware de sessão.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passo a Passso
&lt;/h2&gt;

&lt;p&gt;Adicionando as configurações do cache distribuído, nesse caso será usado o redis. Para utilizar esse métodos de extensão &lt;code&gt;AddStackExchangeRedisCache()&lt;/code&gt; precisamos adicionar o pacote &lt;code&gt;Microsoft.Extensions.Caching.StackExchangeRedis&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AddStackExchangeRedisCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;opt&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ConfigurationOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ConfigurationOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;EndPoints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;Password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;beatriz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InstanceName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CacheDistributed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicionando configurações sobre a sessão&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AddSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IdleTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HttpOnly&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="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IsEssential&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicionando o middleware de sessão à pipeline do app.&lt;/p&gt;

&lt;p&gt;Obs.: Deve estar nesta ordem de chamada antes de &lt;code&gt;MapControllers()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UseSession&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MapControllers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Run&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 podemos utilizar o &lt;code&gt;HttpContext.Session&lt;/code&gt;. Código do &lt;code&gt;SessaoController.cs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sessao&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SessaoController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ControllerBase&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;IActionResult&lt;/span&gt; &lt;span class="nx"&gt;SetSession&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;FromQuery&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;HttpContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Ok&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="nx"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;listar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
       &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;IActionResult&lt;/span&gt; &lt;span class="nx"&gt;GetSession&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HttpContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Ok&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="nx"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&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;h2&gt;
  
  
  Aplicação funcionando
&lt;/h2&gt;

&lt;p&gt;Armazenando um valor na sessão.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qskRydUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gngkylaicd2z5p9wx9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qskRydUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gngkylaicd2z5p9wx9a.png" alt="Adicionando um valor para armazenar na sessão" width="880" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consultando o valor armazenado na sessão&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IxOF-4Op--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3t5eaa3rkop087v0yfz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IxOF-4Op--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3t5eaa3rkop087v0yfz7.png" alt="Listagem dos valores armazenados na sessão" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>aspnetcore</category>
      <category>backend</category>
      <category>session</category>
    </item>
    <item>
      <title>Observabilidade em APIs ASP.NET core</title>
      <dc:creator>Beatriz813</dc:creator>
      <pubDate>Tue, 27 Jul 2021 01:41:47 +0000</pubDate>
      <link>https://dev.to/beatriz813/obsevabilidade-em-apis-asp-net-core-5cil</link>
      <guid>https://dev.to/beatriz813/obsevabilidade-em-apis-asp-net-core-5cil</guid>
      <description>&lt;h2&gt;
  
  
  Ferramentas utilizadas:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Asp.Net core 3.1&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/prometheus-net/prometheus-net" rel="noopener noreferrer"&gt;prometheus-net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.influxdata.com/influxdb/v2.0/" rel="noopener noreferrer"&gt;InfluxDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/docs/grafana/latest/getting-started/getting-started/" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Para este tutorial será construído apenas uma API com Asp.net core que contém um controller, ou seja, o foco aqui é sobre como adicionar um coletor de métricas na sua API. Neste tutorial todas as ferramentas serão instaladas localmente sem uso de Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  InfluxDB
&lt;/h2&gt;

&lt;p&gt;O InfluxDB é um banco de dados (TSDB) usado para armazenar registros onde a data e hora em que eles foram armazenados são relevantes para algum tipo de análise. Portanto, o InfluxDB é usado para armazenar métricas de servidor, monitoramento de desempenho de aplicativos, dados de rede, dados de sensores, eventos, negociações em um mercado e outros tipos de dados analíticos. Ele possui uma linguagem própria chamada Influx que se utiliza do paradigma funcional e oferece várias funções para manipular e analisar dados.&lt;br&gt;
  O InfluxDB pode ser usado com Docker ou instalando o banco de dados na sua máquina. Para instalar o InfluxDB basta baixar o pacote comprimido no site &lt;a href="https://docs.influxdata.com/influxdb/v2.0/install/?t=Windows#download-and-install-influxdb-v20" rel="noopener noreferrer"&gt;InfluxData&lt;/a&gt; e descomprimir na pasta &lt;code&gt;C:\Program Files\InfluxData\&lt;/code&gt;, após isso basta abrir o terminal do seu computador e rodar o binário do banco de dados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"C:&lt;/span&gt;&lt;span class="se"&gt;\P&lt;/span&gt;&lt;span class="s2"&gt;rogram Files&lt;/span&gt;&lt;span class="se"&gt;\I&lt;/span&gt;&lt;span class="s2"&gt;nfluxData&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;
  ./influxd
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após isso você consegue acessar a UI do influxDB que fica por padrão no endereço &lt;code&gt;http://localhost:8086&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Grafana
&lt;/h2&gt;

&lt;p&gt;O grafana é uma aplicação de código aberto onde é possível criar dashboards que refletem os dados que estão armazenados em alguma fonte de dados que você especifica. Ele pode ser usado de duas formas: como container Docker ou instalado localmente. Para instalar basta entrar no &lt;a href="https://grafana.com/grafana/download?platform=windows" rel="noopener noreferrer"&gt;site do Grafana&lt;/a&gt; e selecionar o seu sistema operacional. Se você estiver no windows baixe o arquivo .msi e siga o instalador. Após finalizar a instalação o servidor do grafana ja estará rodando na porta 3000 &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Asp.Net Core 3.1
&lt;/h2&gt;

&lt;p&gt;Aqui será usado Visual Studio 2019. Crie uma API Asp.Net Core 3.1 com os seguintes passos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecione a opção &lt;strong&gt;Criar um projeto&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Selecione o projeto &lt;strong&gt;Aplicativo Web ASP.NET Core&lt;/strong&gt; e dê o nome que desejar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Após essa criação adicione o seguinte pacote &lt;a href="https://github.com/prometheus-net/prometheus-net" rel="noopener noreferrer"&gt;prometheus-net.AspNetCore&lt;/a&gt;&lt;br&gt;
  Se você não sabe instalar um pacote, segue as instruções:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecione a opção &lt;strong&gt;Ferramentas&lt;/strong&gt; &amp;gt; &lt;strong&gt;Gerenciador de pacotes do NuGet&lt;/strong&gt; &amp;gt; &lt;strong&gt;Gerenciar pacotes do NuGet para a Solução&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Na janela que irá abrir selecione a aba &lt;strong&gt;Procurar&lt;/strong&gt; e digite o nome do pacote.&lt;/li&gt;
&lt;li&gt;Após encontrar o pacote selecione ele e instale na sua solução.&lt;/li&gt;
&lt;/ul&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%2Fcbalijv57a9nn59c6ueb.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%2Fcbalijv57a9nn59c6ueb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após fazer isso basta você adicionar o middleWare do prometheus para expor as metricas da sua API no endpoint &lt;code&gt;/metrics&lt;/code&gt;. O &lt;code&gt;app.UseHttpMetrics()&lt;/code&gt; deve ser posto após &lt;code&gt;app.UseRouting()&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IWebHostEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&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="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseRouting&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;UseHttpMetrics&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;UseEndpoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoints&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;endpoints&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;span class="n"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapMetrics&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;Quando você rodar a sua API e consultar o endpoint &lt;code&gt;/metrics&lt;/code&gt; verá o seguinte resultado:&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%2F5zln07mm1rwsqatdh6jd.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%2F5zln07mm1rwsqatdh6jd.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Salvando as métricas no InfluxDB
&lt;/h2&gt;

&lt;p&gt;O InfluxDB tem os buckets que são onde as métricas são armazenadas, porém com Asp.net core você só tem ferramentas/pacotes que te possibilitam escrever e consultar esse bucket, não tem um pacote que colete e insira os dados diretamente no bucket. Para isso o InfluxDB também oferece os scrapers que são coletores que buscam dados de um endpoint informado por você que expõe as métricas no &lt;a href="https://prometheus.io/docs/instrumenting/exposition_formats/" rel="noopener noreferrer"&gt;padrão de escrita Prometheus&lt;/a&gt;. Esses Scrapers ficam varrendo o endpoint que você informou e guarda os dados que encontra no bucket informado por você.&lt;br&gt;
  Para utilizar o Scrapper você precisa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criar um Bucket&lt;/li&gt;
&lt;li&gt;Criar um Scraper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você não souber como criar assista o video. &lt;a href="https://www.loom.com/share/c2c452df29414344b67c7ad470ebdabc" rel="noopener noreferrer"&gt;Criando buckets e scrapers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vale ressaltar que na opção "Target URL" para criar o scraper você deve informar o endpoint de métricas da sua API.&lt;br&gt;
Após isso, quando você rodar a sua API e começar a fazer requisições para ela os dados serão inseridos nos buckets, e você vai poder visualizar que eles estão sendo salvos através da opção &lt;strong&gt;Explore&lt;/strong&gt; na interface gráfica do InfluxDB &lt;code&gt;http://localhost:8086&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%2Fkgkmat06uhwqyv9aeiyy.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%2Fkgkmat06uhwqyv9aeiyy.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando Dashboard no Grafana
&lt;/h2&gt;

&lt;p&gt;Depois de ter instalado o grafana você deve acessar o endereço &lt;code&gt;http://localhost:3000&lt;/code&gt;, fazer login e começar os preparativos para visualizar os seus dados que estão armazenados no InfluxDB. Para isso você deve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adicionar a fonte de dados do InfluxDB&lt;/li&gt;
&lt;li&gt;Criar o Dashboard de forma que cada quadro represente uma query ao Bucket&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assista o &lt;a href="https://www.loom.com/share/ecfab9b189d24a79a2fb48fb3faf78d9" rel="noopener noreferrer"&gt;vídeo&lt;/a&gt; para saber como fazer os dois passos anteriores.&lt;/p&gt;

&lt;p&gt;Se você não conhece a forma de escrita com Influx e não tem intimidade com ela você pode utilizar o construtor de query (Query Builder), selecionar os parâmetros que você quer visualizar e depois copiar o script gerado em &lt;strong&gt;Script Editor&lt;/strong&gt; (Esse procedimento é mostrado no vídeo sugerido logo acima).&lt;br&gt;
Uma informação que acho relevante citar aqui é: você pode verificar os tipos de dados disponibilizados pela ferramenta prometheus-net.AspNetCore olhando o seu endpoint &lt;code&gt;/metrics&lt;/code&gt;. Cada métrica tem um breve resumo com a sua descrição (#HELP) e tipo (#TYPE).&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%2Fa5lqqht40zp7w4ia5xp8.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%2Fa5lqqht40zp7w4ia5xp8.png" alt="exemplo de métricas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Saber o tipo de informação disponibilizada te ajudará a escolher o tipo de gráfico correto para a sua visualização.&lt;/p&gt;

&lt;p&gt;Com o prometheus-dotnet você também pode criar suas próprias métricas, em um próximo tutorial demonstrarei como pode ser feito!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tutorial para Aplicar Migrations em Aplicações ASP.NET</title>
      <dc:creator>Beatriz813</dc:creator>
      <pubDate>Sat, 24 Jul 2021 17:19:51 +0000</pubDate>
      <link>https://dev.to/beatriz813/aplicando-migrations-em-aplicacao-asp-net-ekk</link>
      <guid>https://dev.to/beatriz813/aplicando-migrations-em-aplicacao-asp-net-ekk</guid>
      <description>&lt;p&gt;Para realizar esta tarefa criei dois projetos para exemplificar os dois métodos possíveis a fim de criar e mapear classes para tabelas em bancos de dados. Um utilizando System.ComponentModel.DataAnnotations e outro o método OnModelCreating.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usando OnModelCreating
&lt;/h2&gt;

&lt;p&gt;O primeiro projeto a ser criado é o ef-sem-annotations, criamos ele através do comando:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1C1QMKnb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vm7u97qlfmrsiiynrl08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1C1QMKnb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vm7u97qlfmrsiiynrl08.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nele iremos precisar instalar dois pacotes o MySql.Data.EntityFrameworkCore versão 8.0.22 e Microsoft.EntityFrameworkCore.Design versão 3.1.10.&lt;/p&gt;

&lt;p&gt;Após a criação do projeto criamos a classe Pessoa que irá representar a nossa tabela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aTeji0X4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftsgnwrlsjrr9pq4p08v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aTeji0X4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftsgnwrlsjrr9pq4p08v.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois criamos a classe DataContext que será a nossa orquestradora, onde iremos declarar efetivamente que a classe Pessoa é o mapeamento de uma tabela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--69Lub3N_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oz4f6s6n8q6k47temcvs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--69Lub3N_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oz4f6s6n8q6k47temcvs.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O próximo passo é criar a connection string com o nosso banco de dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pl6O9017--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqosx2eepxm58fx4m8qb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pl6O9017--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqosx2eepxm58fx4m8qb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso podemos aplicar a migration com os seguintes comandos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OHurEuCo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxh3fu3i802t153jen49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OHurEuCo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxh3fu3i802t153jen49.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VsJs7k_I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdd6vt2jqf165fq35y1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VsJs7k_I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdd6vt2jqf165fq35y1y.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao aplicar a migration podemos conferir o resultado no banco de dados. Repare nos tipos e nas regras de cada coluna, são bem genéricas. Mas isso acontece por que não aplicamos nenhuma regra.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hu56KWmk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pc6gp9pl6vxragdo71n3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hu56KWmk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pc6gp9pl6vxragdo71n3.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O primeiro modo de aplicar regras a essa migration é utilizando a sobrescrita do método OnModelCreating na classe DataContext.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rBdhW28G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqzvsq6oh1mzau23wvd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rBdhW28G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqzvsq6oh1mzau23wvd5.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repare que agora os campos Nome e Idade são obrigatórios e o primeiro tem o tamanho máximo de 30 caracteres. Para aplicar essas regras ao banco de dados executamos uma nova migration&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FyX2gq8H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98f8i0jp3jxd4m6xjhe2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FyX2gq8H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98f8i0jp3jxd4m6xjhe2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qMdboZiA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uakwyy6c9zue1qj7zeeu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qMdboZiA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uakwyy6c9zue1qj7zeeu.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso temos o novo resultado no banco de dados:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eLNETHw---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yntawv5nh1wd2xtusd5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eLNETHw---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yntawv5nh1wd2xtusd5k.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Usando Annotations
&lt;/h2&gt;

&lt;p&gt;O segundo projeto chamado ef-com-annotations foi criado como uma WebApi também.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iW7dhaoe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48x3ye7udco4czwo7csy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iW7dhaoe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48x3ye7udco4czwo7csy.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nele iremos precisar instalar dois pacotes o MySql.Data.EntityFrameworkCore versão 8.0.22 e Microsoft.EntityFrameworkCore.Design versão 3.1.10.&lt;/p&gt;

&lt;p&gt;Utilizamos o pacote System.ComponentModel.DataAnnotations na construção da classe Pessoa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8_AVXYfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rls8haah0kmv1g6x37w0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8_AVXYfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rls8haah0kmv1g6x37w0.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A classe DataContext fica:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xM5j1fPX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ynzb1a4fnrd3z61xf02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xM5j1fPX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ynzb1a4fnrd3z61xf02.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A nossa string de conexão fica:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qsSZeV63--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emqwwgjfi0xvo97fcqjk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qsSZeV63--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emqwwgjfi0xvo97fcqjk.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E então podemos aplicar a nossa migration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PQihoV3B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h6ylgohu05v5k2c0sgw8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PQihoV3B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h6ylgohu05v5k2c0sgw8.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Eh74xaqG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8q920j1bi1nw1rtldn2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eh74xaqG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8q920j1bi1nw1rtldn2.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O resultado desse código no banco de dados é o seguinte:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--34WJiHEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpzgcuvnqupo8erebp4m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--34WJiHEV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpzgcuvnqupo8erebp4m.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repare que em ambos métodos chegamos ao mesmo resultado, porém um com menos código que outro. Essas são duas formas possíveis de mapear classes para bancos de dados, basta você analisar qual das duas é mais adequada para a sua solução.                &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Como criar uma extensão para contabilizar o tempo que você passa em páginas Web </title>
      <dc:creator>Beatriz813</dc:creator>
      <pubDate>Fri, 12 Jun 2020 22:45:26 +0000</pubDate>
      <link>https://dev.to/beatriz813/como-criar-uma-extensao-para-contabilizar-o-tempo-que-voce-passa-em-paginas-web-2f8f</link>
      <guid>https://dev.to/beatriz813/como-criar-uma-extensao-para-contabilizar-o-tempo-que-voce-passa-em-paginas-web-2f8f</guid>
      <description>&lt;ul&gt;
&lt;li&gt;O intuito deste tutorial é incentivar você que é iniciante, e que está sem ideias para criar projetos, a exercitar seus conhecimentos em Javascript. 💙&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Obs.: Recomendo que você visite as documentações das tecnologias usadas.&lt;/p&gt;

&lt;p&gt;O código deste projeto está disponível no &lt;a href="https://github.com/Beatriz813/Extensao-Chrome-gerenciador-Tempo"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resultado da extensão
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hh6mSPAx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/div6nkr6od3keqde4s9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hh6mSPAx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/div6nkr6od3keqde4s9l.png" width="500px" height="300px"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tecnologias usadas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;HTML5&lt;/li&gt;
&lt;li&gt;CSS3&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.chartjs.org/"&gt;Chartjs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/apps/api_index"&gt;Chrome Web APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/extensions/getstarted"&gt;Chrome extension tutorial*&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Explicando a ideia da extensão
&lt;/h2&gt;

&lt;p&gt;A ideia é criar uma extensão para o Google Chrome visando contabilizar quanto tempo uma página Web (site) fica aberta em nossos navegadores. Vamos partir do princípio que o tempo passado em uma página Web deve ser contabilizado desde o momento em que ela é carregada/inicializada até o momento que mudamos para outro site dentro da mesma aba ou a fechamos.&lt;/p&gt;

&lt;h2&gt;
  
  
  O Código
&lt;/h2&gt;

&lt;p&gt;Primeiro de tudo devemos criar o arquivo &lt;code&gt;manifest.json&lt;/code&gt;, nele iremos declarar informações sobre a nossa extensão e também alguns arquivos que iremos utilizar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Monitor de sites"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content_scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;all_urls&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"background.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"tabs"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"browser_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"default_popup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"default_icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"work.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Monitor de sites"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Irei explicar algumas propriedades desse arquivo que acho relevante saber para esse projeto. (Se quiser saber mais sobre o &lt;code&gt;manifest.json&lt;/code&gt; acesse a &lt;a href="https://developer.chrome.com/extensions/manifest"&gt;documentação do google&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A propriedade &lt;em&gt;background&lt;/em&gt; é onde definimos o nosso script principal que mantém todo o gerenciamento de tempo em cada aba.&lt;/li&gt;
&lt;li&gt;A propriedade &lt;em&gt;permissions&lt;/em&gt; serve para nos dar acesso a APIs que iremos utilizar na nossa extensão&lt;/li&gt;
&lt;li&gt;A propriedade &lt;em&gt;browser_action&lt;/em&gt; define como o icone da nossa extensão será mostrado no canto superior direito do navegador e também qual conteúdo será apresentado para o usuário quando clicado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Arquivo background.js
&lt;/h3&gt;

&lt;p&gt;Aqui temos acesso à API do &lt;strong&gt;chrome&lt;/strong&gt;. Nele vamos "escutar" o objeto tabs, quando ele for atualizado e quando for fechado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onUpdated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabAtualizada&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onRemoved&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabFechada&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;A função de callback &lt;strong&gt;tabAtualizada&lt;/strong&gt; recebe três parâmetros de entrada &lt;em&gt;tabId, changeInfo, tab&lt;/em&gt; onde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;tabId&lt;/em&gt; é o id da tab atualizada&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;changeInfo&lt;/em&gt; contém informações sobre o status da aba (se ela ja carregou ou se está carregando)&lt;/li&gt;
&lt;li&gt;Objeto &lt;em&gt;tab&lt;/em&gt; que traz algumas informações referentes ao conteúdo carregado na aba.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Já a função de callback &lt;strong&gt;tabFechada&lt;/strong&gt; traz apenas o id da aba fechada.&lt;/p&gt;

&lt;p&gt;Na função &lt;strong&gt;tabAtualizada&lt;/strong&gt; é preciso verificar se o status da página está como "complete" (se ela carregou) e também se a url da aba é diferente de "chrome://" pois o tempo em páginas referentes ao navegador não nos é interessante.&lt;br&gt;
Para melhorar a visualização do algoritmo observe este fluxograma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kUq6vGTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pl91glh74ow5855lcmeq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kUq6vGTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pl91glh74ow5855lcmeq.png" alt="abrir aba"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já na função &lt;strong&gt;tabFechada&lt;/strong&gt; seguiremos esta linha de pensamento:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IwVuedLk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3yqjgnbphlooduvan6cu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IwVuedLk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3yqjgnbphlooduvan6cu.png" alt="fechar aba"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Todo o tempo passado nos sites é guardado em um array no localStorage. Quando vamos no arquivo &lt;code&gt;principal.js&lt;/code&gt; e recuperamos essas informações do localStorage, é preciso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criar um array com o nome dos sites acessados
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dado&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;dadosNavegacao&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;titulo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tempo&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;
    &lt;span class="nx"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;tempo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;temp&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;Criar um array de cores de acordo com a quantidade de sites armazenados
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;cores&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;coresPadrao&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;coresBorda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;coresBorda&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;coresBordaPadrao&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;Criar o gráfico
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tempo nos Sites (em minutos)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tempo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cores&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;coresBorda&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;borderWidth&lt;/span&gt;&lt;span class="p"&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="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;maintainAspectRatio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;tooltips&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
        &lt;span class="na"&gt;scales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;yAxes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;beginAtZero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="na"&gt;xAxes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;ticks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;beginAtZero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="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;Espero que este tutorial tenha incentivado e ajudado você a criar uma extensão para o Google Chrome. &lt;br&gt;
😘  🌈&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>extension</category>
      <category>chartjs</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>React Native com mapa e geolocalização (Aplicativo Android)</title>
      <dc:creator>Beatriz813</dc:creator>
      <pubDate>Wed, 27 May 2020 23:44:58 +0000</pubDate>
      <link>https://dev.to/beatriz813/react-native-com-mapa-e-geolocalizacao-aplicativo-android-4ec1</link>
      <guid>https://dev.to/beatriz813/react-native-com-mapa-e-geolocalizacao-aplicativo-android-4ec1</guid>
      <description>&lt;h2&gt;
  
  
  Tecnologias utilizadas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/react-native-community/react-native-maps" rel="noopener noreferrer"&gt;react-native-maps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Agontuk/react-native-geolocation-service" rel="noopener noreferrer"&gt;react-native-geolocation-service&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  react-native-maps
&lt;/h3&gt;

&lt;p&gt;Instalamos o pacote através do seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add react-native-geolocation-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Devemos adicionar o seguinte código em &lt;code&gt;android/app/src/main/AndroidManifest.xml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;application&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;meta-data&lt;/span&gt;
    &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.google.android.geo.API_KEY"&lt;/span&gt;
    &lt;span class="na"&gt;android:value=&lt;/span&gt;&lt;span class="s"&gt;"Sua API KEY do google maps"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- You will also only need to add this uses-libray tag --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;uses-library&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"org.apache.http.legacy"&lt;/span&gt; &lt;span class="na"&gt;android:required=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para as versões do react native inferiores a 0.60 deve ser realizado o seguinte passo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Caso a sua versão seja superior ou igual a 0.60 esse passo torna-se desnecessário&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Arquivo: build.gradle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ext {
  compileSdkVersion   = 28
  buildToolsVersion   = "28.0.3"
  minSdkVersion       = 16
  targetSdkVersion    = 28

  // Any of the following will work
  googlePlayServicesVersion      = "17.0.0"
  // playServicesVersion         = "17.0.0"
  // playServicesLocationVersion = "17.0.0"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Gerando a chave de API Google Maps
&lt;/h4&gt;

&lt;p&gt;Para realizar esta etapa você precisa ter uma conta no google e precisa acessar o seguinte &lt;a href="https://cloud.google.com/console/google/maps-apis/overview" rel="noopener noreferrer"&gt;endereço&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você deve logar com a sua conta do google. Após o login a seguinte tela será apresentada para você&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%2Fi%2F933kwlonrsb3tmfa2kw4.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%2Fi%2F933kwlonrsb3tmfa2kw4.png" alt="Primeira tela"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aceite os termos e continue.&lt;/p&gt;

&lt;p&gt;Selecione a opção &lt;strong&gt;API&lt;/strong&gt; no menu lateral e crie um novo projeto, digite o nome do seu projeto&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%2Fi%2Fj06iaa3vlycpmievtsk8.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%2Fi%2Fj06iaa3vlycpmievtsk8.png" alt="Terceira tela"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após criar o seu projeto a seguinte tela será apresentada. Nesse dashboard selecione a opção &lt;strong&gt;Maps SDK for Android&lt;/strong&gt; e clique no botão ativar&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%2Fi%2Fknx2si2ue2jwayvclpir.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%2Fi%2Fknx2si2ue2jwayvclpir.png" alt="Quarta tela"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após esse passo você deve selecionar a opção &lt;strong&gt;Credenciais&lt;/strong&gt; no menu lateral e clicar em &lt;em&gt;Credenciais em APIs e serviços&lt;/em&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%2Fi%2Fvu4hnpw6mlcgpx2jbn37.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%2Fi%2Fvu4hnpw6mlcgpx2jbn37.png" alt="Sétima tela"&gt;&lt;/a&gt;&lt;br&gt;
Isso te levará para essa tela onde você irá clicar em &lt;strong&gt;CRIAR CREDENCIAIS&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%2Fi%2Fe2ta0omyhdpm2otj5lhn.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%2Fi%2Fe2ta0omyhdpm2otj5lhn.png" alt="Oitava tela"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E logo será criada a sua chave de API&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%2Fi%2Fhlev3yhq3k4n4rrz5jy0.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%2Fi%2Fhlev3yhq3k4n4rrz5jy0.png" alt="nona tela"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  react-native-geolocation-service
&lt;/h3&gt;

&lt;p&gt;Instalamos o pacote com o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add react-native-geolocation-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Devemos adicionar as permissões no arquivo &lt;code&gt;android/app/src/main/AndroidManifest.xml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.ACCESS_COARSE_LOCATION"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;uses-permission&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.ACCESS_FINE_LOCATION"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  No Código
&lt;/h2&gt;

&lt;p&gt;Para pegar a localização atual do usuário iremos utilizar o objeto Geolocation do pacote &lt;code&gt;react-native-geolocation-service&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Geolocation&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-geolocation-service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;minhaLocalizacao&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMinhaLocalizacao&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Geolocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCurrentPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;setMinhaLocalizacao&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;latitudeDelta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0922&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;longitudeDelta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0421&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minha localização =&amp;gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;minhaLocalizacao&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// See error code charts below.&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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="na"&gt;enableHighAccuracy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maximumAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10000&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="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 parâmetros do método &lt;code&gt;getCurrentPosition(sucesso(), erro(), opções)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Como estou escrevendo os componentes como funções tive que usar o &lt;code&gt;useEffect()&lt;/code&gt;, e para que ele execute apenas uma vez é preciso passar um array vazio como segundo parâmetro para que ele se comporte como se fosse no método &lt;code&gt;componentDidMount&lt;/code&gt;. &lt;a href="https://pt-br.reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects" rel="noopener noreferrer"&gt;Referência da documentação&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para utilizar a localização obtida vamos usar o component MapView do pacote &lt;code&gt;react-native-maps&lt;/code&gt; para renderizar o nosso mapa&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MapView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-maps&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MapView&lt;/span&gt;
        &lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;minhaLocalizacao&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;570&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="nx"&gt;showsUserLocation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getLocalizacao&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Com isso temos um mapa que marca a sua localização inicial.&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%2Fi%2Fv1jjnjw20a8czcffapeh.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%2Fi%2Fv1jjnjw20a8czcffapeh.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você tirar o atributo &lt;code&gt;{{ width: 360, height: 570}}&lt;/code&gt; talvez o mapa não apareça.&lt;/p&gt;

&lt;p&gt;Podemos também inserir marcadores no mapa utilizando o componente Marker do pacote &lt;code&gt;react-native-maps&lt;/code&gt;. E utilizar o atributo &lt;code&gt;onPress&lt;/code&gt; do componente MapView para pegar a localização de onde a pessoa clicou no mapa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MapView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Marker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-maps&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MapView&lt;/span&gt;
        &lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;minhaLocalizacao&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="nx"&gt;showsUserLocation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;showsMyLocationButton&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;moveOnMarkerPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getLocalizacao&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Marker&lt;/span&gt;
          &lt;span class="nx"&gt;coordinate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posicaoMarcador&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/MapView&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O atributo coordinate do componente Marker deve receber um objeto assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nx"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esse pedaço de código você pode clicar em um ponto qualquer do mapa e ele será marcado como na imagem a seguir&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%2Fi%2Fj5aieeexslz1m5wu42d7.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%2Fi%2Fj5aieeexslz1m5wu42d7.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dado este tutorial agora você terá uma base para inserir mapas no seu aplicativo android.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>geolocalocation</category>
      <category>map</category>
    </item>
  </channel>
</rss>
