<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Allan Barbosa on Medium]]></title>
        <description><![CDATA[Stories by Allan Barbosa on Medium]]></description>
        <link>https://medium.com/@allbarbos?source=rss-5b64da95c95c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*y6C2JaFMdOeTOKBML-iMpg.jpeg</url>
            <title>Stories by Allan Barbosa on Medium</title>
            <link>https://medium.com/@allbarbos?source=rss-5b64da95c95c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 07:16:32 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@allbarbos/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Como reduzimos em ~90% o tempo de resposta de um serviço core do Will]]></title>
            <link>https://medium.com/tech-will/como-reduzimos-em-90-o-tempo-de-resposta-de-um-servi%C3%A7o-core-do-will-265cef6aadc?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/265cef6aadc</guid>
            <category><![CDATA[circuit-breaker]]></category>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[caching]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[tech]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Thu, 14 Jul 2022 18:37:34 GMT</pubDate>
            <atom:updated>2022-07-14T18:37:34.720Z</atom:updated>
            <content:encoded><![CDATA[<p>Aqui no will utilizamos a abordagem de microsserviços, e como você já deve imaginar, temos muitos serviços em determinados contextos/produto. Portanto, nesse post quero compartilhar com você o resultado de uma refatoração que aplicamos em um dos<strong> serviços core que suportam o Pix do will.</strong></p><p>Em outubro de 2021, começamos a notar um aumento significativo no tempo de resposta desse serviço. Ligamos o farol amarelo em nossos monitoramentos e acompanhamos de perto para entender o motivo desse aumento (para ver se não era algo pontual). No entanto continuou com uma certa constância, até que em fevereiro de 2022 isso começou a onerar nosso SLI de disponibilidade.</p><p>Nesse meio tempo iniciamos uma <a href="https://www.industrialempathy.com/posts/design-docs-at-google">Design Doc</a> com o objetivo de propor uma solução que reduzisse significativamente o tempo de resposta. Isso porque quanto mais rápido esse serviço fosse, mais percepção de valor nosso cliente teria do produto — afinal, essa lentidão gerava muito contact rate <em>(indicador de negócio e termômetro da experiência do cliente)</em>.</p><p>Após o levantamento e análise do contexto geral, elencamos alguns ofensores:</p><ol><li><strong>Arquitetura não escalável;</strong></li><li><strong>Ausência de uma estratégia eficiente de cache;</strong></li><li><strong>Não tolerante a falhas;</strong></li><li><strong>Linguagem de programação.</strong></li></ol><h3>1. Arquitetura não escalável</h3><p>A falta de planejamento e tempo hábil para criar uma arquitetura evolutiva, que suportasse o crescimento do negócio ao longo do tempo, foi o primeiro sintoma que emergiu. Notamos também que era necessário entender mais a fundo aquele domínio de negócio mediante a tantas integrações de sistemas que ali existiam, para que ao final, fosse possível alcançar uma solução tolerante a falhas e resiliente.</p><p><em>Nesse momento tínhamos o seguinte cenário:</em></p><p>Uma <strong>API Core</strong> chamava outra <strong>API (Contexto A)</strong> para validar a informação da conta do cliente. No entanto, por trás do <strong>Contexto A</strong> existiam ainda mais 4 API’s nesse fluxo, resultando assim em 5 requisições HTTP — o que estava mais do que claro que iria falhar em diversos momentos, principalmente ao integrar com sistemas externos.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IpbVt4yCgnspnTwr9nPaMg.jpeg" /><figcaption>Architecture Blueprint versão 1</figcaption></figure><p>A primeira coisa que fizemos foi conversar com os especialistas de domínio para entender se existia realmente a necessidade de tantas integrações, pois olhando para o código implementado parecia existir uma certa repetição. Após alguns estudos, chegamos à conclusão que seria suficiente utilizar apenas o <strong>Contexto B</strong> para validar a informação que a <strong>API Core</strong> necessitava, então demos o primeiro passo removendo o que não era necessário.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UnwP1-0BOHu24eeMjXWRBQ.jpeg" /><figcaption>Architecture Blueprint versão 2</figcaption></figure><p>Nesse momento foi possível reduzir boa parte do tempo de resposta. Contudo, não ter uma estratégia de resiliência nos incomodava muito, pois se a <strong>API Contexto A</strong> caísse teríamos novamente aumento de contact rate.</p><h3>2. Estratégia de cache</h3><p>Quando pensamos em desenvolvimento moderno de software, na maior parte do tempo estamos falando sobre caching.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/597/1*oyxFiJP5885oIOkBk-4DNg.jpeg" /><figcaption>Imagem retirada do filme Toy Story, com os personagens Woody e Buzz Lightyear e a legenda “Caching, caching everywhere”</figcaption></figure><p>Aqui não foi diferente: ao identificarmos que o estado da informação que a <strong>API Core</strong> consultava não sofria tanta alteração, a primeira ideia foi…</p><blockquote>“Vamos colocar uma camada de cache e ser felizes!”</blockquote><p>A ideia era muito boa e traria um ganho significativo no fluxo, mas esbarramos em problema de capacidade de time: a implementação dessa camada de cache não caberia no planejamento, pois tínhamos uma equipe pequena com um backlog já gigante.</p><p>Foi assim que decidimos adicionar um API Gateway com a estratégia de response cache, sendo necessário apenas alguns arquivos yaml para configurar tudo, chegando na seguinte arquitetura:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZhJkOfScQHiiqG26h4yp5A.jpeg" /><figcaption>Architecture Blueprint versão 3</figcaption></figure><p>Basicamente configuramos:</p><p>- API Gateway <a href="https://docs.konghq.com/gateway/2.8.x/reference/db-less-and-declarative-config">Kong em modo DB-Less</a>;<br>- Plugin para cache de response com Redis (TTL de 4 horas);<br>- Exposição de endpoints para a <strong>API Contexto A.</strong></p><h3>3. Tolerância a falhas</h3><p>Reduzir conexões e adicionar a camada de cache já traria um resultado significativo, mas ainda havia a necessidade de evitar falhas em cascata, já que temos chamada HTTP para fora do contexto <strong>Core</strong> e sabemos que isso é problema (as <a href="https://blogs.oracle.com/developers/post/fallacies-of-distributed-systems">falácias da computação distribuída</a> estão aí para provar).</p><p>Sendo assim, decidimos utilizar o padrão <a href="https://martinfowler.com/bliki/CircuitBreaker.html">Circuit Breaker</a> que permite um fluxo mais tolerante a falhas e resiliente, que “sobrevive” quando os principais serviços que a <strong>API Core</strong> consome estiverem passando por instabilidade. Assim, o blueprint final da arquitetura ficou dessa forma:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KznAH78N8puDGC6kYBdQrA.jpeg" /><figcaption>Architecture Blueprint versão 4 — Final</figcaption></figure><h3><strong>4. Linguagem de programação</strong></h3><p>Optamos em testar uma nova linguagem. Sabíamos que escrevendo essa solução em <a href="https://go.dev/"><strong>Go</strong></a> teríamos um enorme ganho em economia de infraestrutura e startup do projeto, pois nossa solução trabalhava em média com 150MB de memória e seu startup chegava a 5 minutos (o que dificultava muito a subida/escala de novos pods no <a href="https://kubernetes.io/pt-br">K8S</a>).</p><p>Havia ainda outros contextos dentro do time que precisavam realizar processos concorrentes ou paralelos, tornando-se aprazível o uso de <strong>Go Routines</strong>.</p><p>De forma geral achamos Go uma linguagem com baixa curva de aprendizagem, o que nos possibilitou uma entrega muito rápida do projeto e, ao colocar em produção, atingimos números admiráveis (que compartilho na sequência).</p><h3>Resultados obtidos</h3><ul><li>Consumo de memória reduzido em <strong>80%</strong> - <em>150MB para 30MB</em>.</li><li>Redução no tempo de inicialização do serviço em <strong>99,3%</strong> - <em>5 minutos para 2 segundos</em>.</li><li>Consumo de CPU reduzido em <strong>97,5% </strong>- <em>4% para 0,1%</em>.</li><li>Tamanho da imagem docker reduzido em <strong>91,6%</strong> - <em>168MB para 14MB</em>.</li><li>Tempo de resposta reduzido em <strong>90,83%</strong> - <em>120ms para 11ms</em>.</li><li>A camada de cache reutiliza <strong>90%</strong> das requisições, evitando ir até o destino e removendo uma grande carga da <strong>API Contexto A</strong>.</li><li>Caso a <strong>API Contexto A</strong> fique fora do ar, o sistema <strong>Core</strong> consegue operar durante <strong>4 horas</strong> retornando erro apenas para <strong>10%</strong> das requisições.</li></ul><p>Esses foram os resultados que obtivemos dessa experiência aqui dentro do will. E você, já testou algo parecido? Fique à vontade para comentar e contar pra gente!</p><h4>Referências</h4><ul><li><a href="https://www.industrialempathy.com/posts/design-docs-at-google">Design Docs at Google</a></li><li><a href="https://docs.konghq.com/gateway/2.8.x/reference/db-less-and-declarative-config/">DB-less and Declarative Configuration - v2.8.x | Kong Docs</a></li><li><a href="https://blogs.oracle.com/developers/post/fallacies-of-distributed-systems">Fallacies of distributed systems</a></li><li><a href="https://martinfowler.com/bliki/CircuitBreaker.html">bliki: Circuit Breaker</a></li></ul><p><em>Quer fazer parte de um time incrível, construir um banco do zero e democratizar o crédito para milhões de brasileiros? </em><a href="https://bit.ly/3aBbAzV"><em>Veja nossas vagas e vem ser will!</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=265cef6aadc" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tech-will/como-reduzimos-em-90-o-tempo-de-resposta-de-um-servi%C3%A7o-core-do-will-265cef6aadc">Como reduzimos em ~90% o tempo de resposta de um serviço core do Will</a> was originally published in <a href="https://medium.com/tech-will">will bank</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Github actions e pacotes privados do npm]]></title>
            <link>https://medium.com/allbarbos/github-actions-e-pacotes-privados-do-npm-c48687369b1f?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c48687369b1f</guid>
            <category><![CDATA[jfrog-artifactory]]></category>
            <category><![CDATA[github]]></category>
            <category><![CDATA[npm]]></category>
            <category><![CDATA[jfrog]]></category>
            <category><![CDATA[github-actions]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Sun, 26 Jul 2020 20:12:06 GMT</pubDate>
            <atom:updated>2020-07-26T20:49:14.734Z</atom:updated>
            <content:encoded><![CDATA[<p>Hoje quebrei a cabeça por horas para funcionar a instalação de pacotes privados dentro do github actions, por isso decidi compartilhar aqui caso alguém mais passe pela mesma luta :)</p><p>Neste projeto em questão estou utilizando o JFrog como gerenciador de artefatos, porém essa configuração vai funcionar para qualquer outro.</p><p>Adicionei 3 variáveis em meu <strong><em>.npmrc </em></strong><em>(JFROG_API_KEY, JFROG_USERNAME, JFROG_EMAIL) </em>resultando nisso:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*T9vEMZ9yKcPxxCqnyGVsfA.png" /></figure><p>Em seguida criei o arquivo yml da actions <em>(̶̶a̶̶̶ ̶̶̶p̶̶̶r̶̶̶i̶̶̶n̶̶̶c̶̶̶í̶̶̶p̶̶̶i̶̶̶o̶̶̶ ̶̶̶e̶̶̶s̶̶̶t̶̶̶o̶̶̶u̶̶̶ ̶̶̶c̶̶̶o̶̶̶n̶̶̶f̶̶̶i̶̶̶g̶̶̶u̶̶̶r̶̶̶a̶̶̶n̶̶̶d̶̶̶o̶̶̶ ̶̶̶C̶̶̶y̶̶̶p̶̶̶r̶̶̶e̶̶̶s̶̶̶s̶̶̶ ̶̶̶p̶̶̶a̶̶̶r̶̶̶a̶̶̶ ̶̶̶r̶̶̶o̶̶̶d̶̶̶a̶̶̶r̶̶̶ ̶̶̶t̶̶̶e̶̶̶s̶̶̶t̶̶̶e̶̶̶s̶̶̶,̶ ̶p̶o̶r̶é̶m̶ ̶a̶ ̶p̶a̶r̶t̶e̶ ̶ú̶t̶i̶l̶ ̶n̶o̶ ̶c̶o̶n̶t̶e̶x̶t̶o̶ ̶d̶o̶ ̶p̶o̶s̶t̶ ̶s̶ã̶o̶ ̶a̶s̶ ̶l̶i̶n̶h̶a̶s̶ ̶1̶6̶ ̶à̶ ̶2̶1̶ ̶o̶n̶d̶e̶ ̶e̶s̶t̶á̶ ̶o̶c̶o̶r̶r̶e̶n̶d̶o̶ ̶a̶ ̶i̶n̶s̶t̶a̶l̶a̶ç̶ã̶o̶ ̶d̶o̶s̶ ̶p̶a̶c̶o̶t̶e̶s̶)</em>, veja que estou passando como parâmetro as secrets do Github afim de evitar o vazamento de informações sensíveis.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d50b1847aa75916c0bdd5a8eed94f871/href">https://medium.com/media/d50b1847aa75916c0bdd5a8eed94f871/href</a></iframe><h4>Como cadastro secrets?</h4><p>Acesse <strong><em>Settings</em></strong> na barra de ferramentas do seu repositório.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1004/1*B9lIUFbalqAK-13VVxZ1Yw.png" /></figure><p>Clique em <strong><em>Secrets</em></strong> no menu ao lado esquerdo e <strong><em>New secret</em></strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sCFuMu7UL2QKvmuyyeNt3Q.png" /></figure><p>Basicamente é isso, bem simples! :)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SIRq4aEQJKDPo7Ap9qoPgw.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c48687369b1f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/github-actions-e-pacotes-privados-do-npm-c48687369b1f">Github actions e pacotes privados do npm</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Golang — Criando imagens docker like a boss]]></title>
            <link>https://medium.com/allbarbos/golang-criando-imagens-docker-like-a-boss-563e48941203?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/563e48941203</guid>
            <category><![CDATA[multi-stage-builds]]></category>
            <category><![CDATA[go]]></category>
            <category><![CDATA[upx]]></category>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Wed, 17 Jun 2020 19:34:38 GMT</pubDate>
            <atom:updated>2020-06-17T19:34:38.665Z</atom:updated>
            <content:encoded><![CDATA[<h3>Golang — Criando imagens docker like a boss</h3><p>No dia a dia é um saco trabalhar com imagens docker de tamanhos exagerados e na maioria dos casos falta apenas um pouco de carinho pra criar um Dockerfile otimizado.</p><p>Sendo assim decidi compartilhar esse caso que atuei recentemente, onde o problema não era especificamente o tamanho da imagem, mas corroborava pra piorar o cenário e não dava pra deixar como estava.</p><h3>Contexto</h3><p>API Rest com alto throughput de request, rodava no k8s e pasmem, sua imagem final era de 1.04GB.</p><p>Daria pra listar vários problemas, mas nesse contexto pode prejudicar bastante o tempo para escalar novos pods e também no dia a dia o desenvolvimento para baixar imagens.</p><p>Como executamos o binário da aplicação podemos descartar todo o resto do projeto, deixando a imagem infinitamente menor ao manter todos arquivos, com isso podemos utilizar algumas soluções:</p><h3>Alpine</h3><p>Por ser uma distribuição leve, de cara temos uma redução significativa para 600MB sem quebrar muito a cabeça com o Dockerfile</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/725/1*Qy_BnR1TVzzbSK7-nUERkQ.png" /></figure><h3>Flags</h3><p>Se fizer sentido para seu contexto, podemos remover as informações de flags ao compilar o binário, o que nos poupa alguns MBs, neste caso 4</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/730/1*eJHUaVF2sCRiMRn8O0RN9A.png" /></figure><h3>Multi-stage builds</h3><p>Podemos ir além com multi-stage builds e criar uma imagem com apenas o necessário para rodar a aplicação, assim teremos uma redução absurda de 594MB para míseros 21.8MB</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/731/1*pEGtH8czroIK8cpCBr4QXQ.png" /></figure><h3>UPX</h3><p>E a cereja do bolo é o <a href="https://upx.github.io/">UPX</a> que nos permite compactar binário e reduzir ainda mais o tamanho</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/723/1*6L2FiMQAVJo-KoIYWQhhxg.png" /></figure><p>Caso queira ver os dockerfiles que gerei as imagens basta acessar este <a href="https://gist.github.com/allbarbos/687edf4f6cd124452796023b86540dac">gist</a>.</p><p>Basicamente é isso que gostaria de compartilhar e espero conseguir ajudá-lo a criar imagens pequenas :)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*136qhXxInh44-pWrPrkLTw.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=563e48941203" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/golang-criando-imagens-docker-like-a-boss-563e48941203">Golang — Criando imagens docker like a boss</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Criando FaaS e configurando ambiente]]></title>
            <link>https://medium.com/allbarbos/criando-faas-e-configurando-ambiente-6f2ab168b7df?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/6f2ab168b7df</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[aws-lambda]]></category>
            <category><![CDATA[serverless-architecture]]></category>
            <category><![CDATA[lambda]]></category>
            <category><![CDATA[serverless]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Tue, 02 Jul 2019 23:11:23 GMT</pubDate>
            <atom:updated>2019-07-02T23:17:28.447Z</atom:updated>
            <content:encoded><![CDATA[<p>Criar lambdas é um processo simples, porém para não ter minha saúde mental abalada utilizarei o <a href="https://serverless.com/">Serverless Framework</a> afim de facilitar o gerenciamento das funções.</p><p>Para iniciar basta executar os comandos abaixo via CLI.</p><pre>$ serverless create --template aws-nodejs --path consulta-cep<br>$ cd consulta-cep<br>$ npm init -y<br>$ npm i -E serverless serverless-offline</pre><p>A lib <em>serverless-offline</em> nos permite debugar localmente o código e para que tudo funcione corretamente adicionei algumas informações no <em>serverless.yml</em></p><pre>service: consulta-cep</pre><pre>provider:<br>  name: aws<br>  runtime: nodejs10.x<br>  stage: dev<br>  region: us-east-1</pre><pre>functions:<br>  ceps:<br>    handler: src/handler.ceps<br>    events:<br>      - http:<br>          path: ceps/{cep}<br>          method: get<br>          request:<br>          parameters:<br>            paths:<br>              cep: true<br>plugins:<br>  - serverless-offline</pre><p>No <em>Visual Studio Code</em> adicionei o seguinte código para debug:</p><pre>{<br>  &quot;type&quot;: &quot;node&quot;,<br>  &quot;request&quot;: &quot;launch&quot;,<br>  &quot;name&quot;: &quot;Serverless&quot;,<br>  &quot;program&quot;: &quot;${workspaceFolder}/node_modules/.bin/sls&quot;,<br>  &quot;cwd&quot;: &quot;${workspaceFolder}&quot;,<br>  &quot;args&quot;: [&quot;offline&quot;]<br>}</pre><p>Ao executar o projeto (<strong><em>F5</em></strong>) será impresso no console a rota de acesso, basta realizar uma requisição e tudo estará funcionando, inclusive o debug.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UOAynaa7Kdhj4BjIfd7ubA.png" /><figcaption>Debug VS Code</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/627/1*COdvHPCoSl4BApn7UMBxxw.png" /><figcaption>Response</figcaption></figure><p>A partir de agora podemos focar apenas no código que realmente importa! :)</p><p>Sendo assim implementei uma função simplória que consulta o WS dos correios e retorna os dados do CEP em questão, todo o código você pode <a href="https://github.com/allbarbos/serverless/tree/01_criando_faas">acessar no Github</a> e abaixo um snapshot de como ficou a estrutura de pastas e etc.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*4YcCrV22e_hImXzWkfjduQ.png" /></figure><p>A ideia agora é adicionar novas funções neste projeto para que possamos ver como é o funcionamento do projeto e depois realizarmos o deploy disso tudo.</p><p>Porém ficará para o próximo post :)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/760/1*JfEwAfCNLyybHoTGptA6fw.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6f2ab168b7df" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/criando-faas-e-configurando-ambiente-6f2ab168b7df">Criando FaaS e configurando ambiente</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Vamos falar de lambda functions?]]></title>
            <link>https://medium.com/allbarbos/vamos-falar-de-lambda-functions-785696cb4ab7?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/785696cb4ab7</guid>
            <category><![CDATA[serverless-architecture]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[lambda]]></category>
            <category><![CDATA[aws-sam]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Mon, 01 Jul 2019 12:51:10 GMT</pubDate>
            <atom:updated>2019-07-29T12:49:27.593Z</atom:updated>
            <content:encoded><![CDATA[<p>O modelo de desenvolvimento “sem servidor” vem ganhando enorme espaço nos últimos tempos e as <em>Functions as a Service (FaaS)</em> estão no mainstream do rolê, portanto irei compartilhar um pouco do que pude conhecer sobre FaaS com base na cloud da AWS.</p><p>Antes de adentrar nas entranhas do código, é importante ressaltar que FaaS é apenas uma das opções da arquitetura Serverless, se não sabe ainda o que significa o conceito segue abaixo um brevíssimo resumo das palavras de <em>Mike Roberts</em> no artigo<em> </em><a href="https://martinfowler.com/articles/serverless.html"><em>Serverless Architectures</em></a>.</p><blockquote><em>Serverless architectures are application designs that incorporate third-party “Backend as a Service” (BaaS) services, and/or that include custom code run in managed, ephemeral containers on a “Functions as a Service” (FaaS) platform.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/504/1*HbFM8AoCLQK99IwwiDheMQ.png" /></figure><p>Dado o contexto podemos falar brevemente sobre os AWS Lambdas, que são funções que nos permite focar diretamente no desenvolvimento do negócio, descartando toda complexidade para provisionar e gerenciar servidores, ficando por conta da vendor cloud — AWS.</p><p>Os lambdas são cobrados pelo tempo de execução e quantidade de chamadas, podendo ser acionados automaticamente por serviços da AWS ou através de aplicações via HTTP — o período em que o serviço não é requisitado não é cobrado.</p><h4>Como gerenciar seu código</h4><p>Sistema baseado em funções é bem granular, com isso torna-se um tanto quanto doloroso gerenciar inúmeros deploys, reutilização de código e etc.</p><p>Talvez seja mais fácil utilizar alguma plataforma ou framework para obter uma melhor produtividade:</p><ul><li><a href="https://serverless.com/">Serverless Framework</a></li><li><a href="https://docs.aws.amazon.com/serverless-application-model/?id=docs_gateway">AWS SAM</a></li><li><a href="https://github.com/iron-io/functions">IronFunctions</a></li><li><a href="https://github.com/fnproject">Fn Project</a></li><li><a href="https://github.com/openfaas/faas">OpenFaaS</a></li><li><a href="https://openwhisk.apache.org/">Apache OpenWhisk</a></li></ul><h4>Ambiente local para desenvolvimento</h4><p>Um item importantíssimo é como o desenvolvedor poderá simular localmente o mesmo cenário que será deployado, possibilitando realizar debug e testes do código — para demonstrar isso criaremos algumas funções mais a frente através do Serverless Framework, porém caso não esteja utilizando nenhum framework que facilite este processo é possível utilizar a ferramenta <a href="https://github.com/localstack/localstack">localstack</a>.</p><h3>Overengineering</h3><p>Lambdas possui inúmeros pontos positivos, porém tome muito cuidado antes de inseri-los em sua stack de serviços, pois como tudo na vida existem trade-off.</p><h4>Fragmentação</h4><p>Existem várias formas de arquitetar uma aplicação FaaS, lembre-se sempre de como será entregue a esteira de CI/CD e o versionamento de código, pois dependendo do quão fragmentado fique a solução você ganhará milhares de repositórios, pipelines e configurações para gerenciar — <em>e não receberá insalubridade no final do mês para lidar com YAML </em>:)</p><h4>Reutilização de código</h4><p>Reutilizar módulos não é nada trivial, apesar de existir os<a href="https://docs.aws.amazon.com/pt_br/lambda/latest/dg/configuration-layers.html"> Lambdas Layers</a>, então dependendo da linguagem que irá escolher de runtime, realize uma análise de como será reutilizado os módulos e se existe a necessidade.</p><h4><strong>Limite de recursos</strong></h4><p><strong>Alocação de memória:</strong> 128 MB a 3,008 MB, em incrementos de 64 MB.<br><strong>Tempo-limite de processamento:</strong> 900 segundos (15 minutos)<br><strong>Variáveis de ambiente: </strong>4 KB<br><strong>Lambda Layers:</strong> 5<br><strong>Solicitações por segundo:</strong> 10x o limite de execuções simultâneas (forma síncrona, todas as origens) — 10x o limite de execuções simultâneas (forma assíncrona — origens que não são da AWS) — Ilimitado (forma assíncrona — origens de serviços da AWS)</p><p>Veja mais detalhes dos limites na <a href="https://docs.aws.amazon.com/pt_br/lambda/latest/dg/limits.html">docs</a>.</p><p>Com esse breve contexto e sem mais delongas, podemos partir para a epopéia de desenvolvimento em lambdas, sendo assim irei dividir em vários posts para que o conteúdo fique melhor organizado.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=785696cb4ab7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/vamos-falar-de-lambda-functions-785696cb4ab7">Vamos falar de lambda functions?</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Porque utilizar GraphQL?]]></title>
            <link>https://medium.com/allbarbos/porque-utilizar-graphql-5ce1655717f2?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/5ce1655717f2</guid>
            <category><![CDATA[restful-api]]></category>
            <category><![CDATA[restful]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[rest]]></category>
            <category><![CDATA[graphql]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Fri, 04 Jan 2019 21:42:54 GMT</pubDate>
            <atom:updated>2019-07-01T02:11:26.471Z</atom:updated>
            <content:encoded><![CDATA[<p>GraphQL é uma linguagem de consulta a dados para API’s desenvolvida pelo Facebook que nos dá alguns poderes e benefícios citados abaixo.</p><h4>Evolução das APIs</h4><p>O fato não ter uma interface padrão definida facilita a evolução, pois não haveria breaking changes caso necessite agregar mais informações em determinado recurso, pois quem controla o que quer receber é o cliente e não mais o servidor conforme estamos acostumado com o REST.</p><p>Supondo que necessitamos buscar em uma API REST apenas os campos <strong>Nome, Sobrenome </strong>e<strong> Idade</strong> do recurso Usuários, o servidor nos retornaria o resultado abaixo - afinal existe um contrato definido para esse retorno.</p><pre><strong><em>api/v1/usuarios/02723022285</em></strong></pre><pre>{<br>  &quot;nome&quot;: &quot;Erick&quot;,<br>  &quot;sobrenome&quot;: &quot;Enrico Souza&quot;,<br>  &quot;idade&quot;: 27,<br>  &quot;sexo&quot;: &quot;Masculino&quot;,<br>  &quot;rg&quot;: &quot;40.659.657-8&quot;,<br>  &quot;cpf&quot;: &quot;027.230.222-85&quot;,<br>  &quot;nascimento&quot;: &quot;26/11/1991&quot;<br>}</pre><p>Se amanhã houver a necessidade de remover/adicionar um campo precisaríamos criar um novo contrato com o cliente para que ele não seja pego de surpresa, pois quem controla os dados que serão fornecidos é a API.</p><p>Já no cenário do GraphQL esse problema de contrato seria invisível, pois se o cliente deseja consumir apenas os dados <strong>Nome</strong>, <strong>Sobrenome</strong> e <strong>RG </strong>o retorno seria:</p><pre>{<br>  &quot;nome&quot;: &quot;Erick&quot;,<br>  &quot;sobrenome&quot;: &quot;Enrico Souza&quot;,<br>  &quot;rg&quot;: &quot;40.659.657-8&quot;<br>}</pre><p>Ou seja, o fato do cliente controlar os dados que deseja receber acaba se tornando-se mais escalável.</p><h4>Performance</h4><p>Conforme mostrado acima, ao utilizar o GraphQL as requisições se tornam mais rápidas pois o payload trafegado na rede é bem reduzido, afinal será enviado apenas as informações necessárias para a consulta em questão.</p><h4>Vários recursos em request único</h4><p>As consultas acessam as propriedades de um recurso e também seguem suas referências, ou seja, é possível obter todos os dados em um único request e isso traz um enorme ganho de performance, pois se fosse em um cenário REST seria exigido o carregamento de várias URLs para obter outros recursos, sendo assim o GraphQL traz um significativo ganho as aplicações e ainda maior para aquelas que utilizam redes móveis lentas.</p><p>E para finalizar é importante frisar que o GraphQL não tem nenhuma relação com banco de dados ou sistemas de armazenamentos, ele é apenas um ponto de entrada da nossa aplicação que irá nos auxiliar em realizar consultas de dados performáticas.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*omJNTRs-GqduedmhtBtpCA.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5ce1655717f2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/porque-utilizar-graphql-5ce1655717f2">Porque utilizar GraphQL?</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Redis — Básico]]></title>
            <link>https://medium.com/allbarbos/redis-b%C3%A1sico-899d3963611a?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/899d3963611a</guid>
            <category><![CDATA[redis]]></category>
            <category><![CDATA[nosql]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Thu, 03 Jan 2019 13:46:36 GMT</pubDate>
            <atom:updated>2019-01-04T20:08:18.982Z</atom:updated>
            <content:encoded><![CDATA[<h3>Redis — Básico</h3><p>O Redis é uma estrutura de dados armazenada em memória que pode ser utilizada como banco de dados, cache e message broker.</p><p>Ele suporta estruturas de dados como strings, hashes, listas, conjuntos, conjuntos classificados com consultas de intervalo, bitmaps, hyperloglogs, índices geoespaciais com consultas e fluxos radius.</p><p>Aqui vai alguns comandos básicos para brincar:</p><p><strong>Setar uma chave com valor</strong></p><pre>SET birl &quot;birl gates&quot;</pre><p><strong>Obter o valor de uma chave</strong></p><pre>GET birl</pre><p><strong>Deletar uma chave</strong></p><pre>DEL birl</pre><p><strong>Incrementar o valor inteiro de uma chave</strong></p><pre>SET birl 1<br>INCR birl</pre><p>Ao invés de utilizar a função INCR também poderíamos incrementar o valor da seguinte forma:</p><pre>x = GET count<br>x = x + 1<br>SET count x</pre><p>O problema é que ao fazer dessa maneira funcionará somente enquanto houver um único cliente utilizando a chave. Veja o que aconteceria se dois clientes estivessem acessando a chave ao mesmo tempo:</p><p>O cliente A lê a contagem como 10.<br>O cliente B lê a contagem como 10.<br>O cliente A incrementa 10 e configura a contagem para 11.<br>O cliente B incrementa 10 e define a contagem para 11.<br><strong><em>Queríamos que o valor fosse 12, mas em vez disso é 11!</em></strong></p><p>Isso ocorre porque incrementar o valor dessa maneira não é uma operação atômica e a função INCR impedirá que isso aconteça, porque é uma operação atômica.</p><p><strong>Setar tempo de expiração para chave/valor</strong></p><pre>SET birl &quot;birl gates&quot;<br>EXPIRE birl 120</pre><p>A função EXPIRE faz com que a chave exista por um determinado período de tempo em segundos e para obter quanto tempo falta para a expiração da chave basta utilizar TTL</p><pre>TTL birl</pre><p>A função TTL pode ter os seguintes retornos: <br><strong>-2</strong>: Quer dizer que a chave foi expirada e deixou de existir <br><strong>-1</strong>: A chave nunca expirará<br><strong>&gt;= 0</strong>: Segundos que faltam para que a chave expire</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*w74gykcXmGO7Oj3wHIJWkQ.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=899d3963611a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/redis-b%C3%A1sico-899d3963611a">Redis — Básico</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Instalação SQL Server 2017]]></title>
            <link>https://medium.com/allbarbos/instala%C3%A7%C3%A3o-sql-server-2017-6050b68e8c80?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/6050b68e8c80</guid>
            <category><![CDATA[sql-server]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Fri, 31 Aug 2018 17:08:21 GMT</pubDate>
            <atom:updated>2018-08-31T17:12:05.221Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/735/1*UDRsp5nVrx7oXBEXLs0uCQ.png" /></figure><p>Criar as pastas: BackupFiles, DataBaseFiles, LogFiles, SqlServerFiles, TempDBFiles</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/819/1*20lAhdf-X5Ar4SLpQcR4Fg.jpeg" /><figcaption>Clicar em <strong><em>New SQl Server stand-alone installation</em></strong><em> para iniciar</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/837/1*fu9wtkUoOlTarPTiUvD5IA.jpeg" /><figcaption>Neste caso, selecionar apenas <strong>Database Engine Services</strong> e configurar a pasta da instância</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/836/1*c1Q6QdCpkPJU4Nb7qy4MMA.jpeg" /><figcaption>Selecionar o <strong>Mixed Mode</strong> para autenticação e definir uma senha (p@ssw0rd)</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/840/1*Zu9dxv-tAZz8XFZha5Io9A.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/841/1*l-rklDq8ajNzW7Xygjn1Pw.jpeg" /><figcaption>O desempenho do TempDB é afetado de acordo com o número de arquivos que será configurado, neste caso são 4 porque a máquina de instalação possui 4 núcleos/processadores, o correto é dividir de acordo com a quantidade de núcleos da máquina</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/972/1*zgsRTdSH_xaQyX0jJAmlOQ.jpeg" /><figcaption>Abrir o Sql Server Configuration Manager e ativar o SQL Server Agent</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/987/1*3aLY1jqF6jIc9wSWKPdPWw.jpeg" /><figcaption>Habilitar o protocolo TCP/IP e restartar o SQL Server(MSSQLSERVER)</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PO4KF38BY383XZZFs4yMLw.jpeg" /><figcaption>Criar um alias para a máquina de instalação, para facilitar no momento de digitar a conexão. Obs.: Criar alias em SQL Native Client 32bit e 64bit.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/737/1*kPgmA0kXuH6D_jAXUhJ2bg.jpeg" /><figcaption>Através do SQLCMD é possível testar se está tudo funcionando</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6050b68e8c80" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/instala%C3%A7%C3%A3o-sql-server-2017-6050b68e8c80">Instalação SQL Server 2017</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Trocando valores de variáveis]]></title>
            <link>https://medium.com/allbarbos/trocando-valores-de-vari%C3%A1veis-71a052483531?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/71a052483531</guid>
            <category><![CDATA[ecmascript-6]]></category>
            <category><![CDATA[es6]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[swapping-variables]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Mon, 06 Nov 2017 16:13:37 GMT</pubDate>
            <atom:updated>2017-11-07T02:03:44.391Z</atom:updated>
            <content:encoded><![CDATA[<p>Para trocar o valor entre 2 variáveis não precisamos mais criar uma terceira para armazenar um valor temporário.</p><p>É comum encontrarmos por ai o seguinte código:</p><pre>let a = 13;<br>let b = 149;<br>let temp;</pre><pre>temp = a;<br>a = b;<br>b = temp;</pre><pre>console.log(a);<br>console.log(b);</pre><p>No entanto, o ES6 nos permite fazer a mesma coisa com a metade de código:</p><pre>let a = 13;<br>let b = 149;</pre><pre>[a, b] = [b, a];</pre><pre>console.log(a);<br>console.log(b);</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*gBibMvfGtSyPeUhMPBZK5w.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=71a052483531" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/trocando-valores-de-vari%C3%A1veis-71a052483531">Trocando valores de variáveis</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Métodos bacanudos para string]]></title>
            <link>https://medium.com/allbarbos/m%C3%A9todos-bacanudos-para-string-3fb1b27df3c0?source=rss-5b64da95c95c------2</link>
            <guid isPermaLink="false">https://medium.com/p/3fb1b27df3c0</guid>
            <category><![CDATA[repeat]]></category>
            <category><![CDATA[startswith]]></category>
            <category><![CDATA[include]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[endswith]]></category>
            <dc:creator><![CDATA[Allan Barbosa]]></dc:creator>
            <pubDate>Fri, 03 Nov 2017 16:11:23 GMT</pubDate>
            <atom:updated>2017-11-03T16:14:50.226Z</atom:updated>
            <content:encoded><![CDATA[<p>Não precisamos mais utilizar o indexOf para procurar string! o/</p><p><strong>StartsWith<br></strong>Ao utilizar este método podemos verificar se uma string inicia com determinado valor. Devemos passar a string que será procurada e a posição que começará a busca:</p><pre>&quot;Métodos bacanudos para string&quot;.startsWith(&quot;Métodos&quot;) // true<br>&quot;Métodos bacanudos para string&quot;.startsWith(&quot;bacanudos&quot;, 8) // true</pre><p>Lembrando que nem todos os browsers dão suporte a este recurso, sendo assim, para manter a compatibilidade existe o polyfill abaixo:</p><pre>if (!String.prototype.startsWith) {<br>  String.prototype.startsWith = function(searchString, position) {<br>    position = position || 0;<br>    return this.indexOf(searchString, position) === position;<br>  };<br>}</pre><p><strong>EndsWith<br></strong>Contrário ao startsWith, compara se o final da string é igual ao informado. Caso queira comparar um pedaço, basta informar no segundo parâmetro o tamanho a ser considerado na string.</p><pre>&quot;Métodos bacanudos para string&quot;.endsWith(&quot;string&quot;) // true<br>&quot;Métodos bacanudos para string&quot;.endsWith(&quot;bacanudos&quot;, 17) // true</pre><p>O polyfill a ser usado caso o browser não possua suporte é:</p><pre>if (!String.prototype.endsWith)<br>  String.prototype.endsWith = function(searchStr, Position) {      <br>    if (!(Position &lt; this.length))<br>      Position = this.length;<br>    else<br>      Position |= 0;</pre><pre>    return this.substr(Position - searchStr.length,<br>                       searchStr.length) === searchStr;<br>  };</pre><p><strong>Includes<br></strong>O includes é case-sensitivity e verifica se existe determinado valor dentro da string, podendo também passar o parâmetro informando onde iniciará a verificação:</p><pre>&quot;Métodos bacanudos para string&quot;.includes(&quot;para&quot;) // true<br>&quot;Métodos bacanudos para string&quot;.includes(&quot;Para&quot;) // false<br>&quot;Métodos bacanudos para string&quot;.includes(&quot;Métodos&quot;, 1) // false</pre><p>Polyfill:</p><pre>if (!String.prototype.includes) {<br>  String.prototype.includes = function(search, start) {<br>    &#39;use strict&#39;;<br>    if (typeof start !== &#39;number&#39;) {<br>      start = 0;<br>    }<br>    <br>    if (start + search.length &gt; this.length) {<br>      return false;<br>    } else {<br>      return this.indexOf(search, start) !== -1;<br>    }<br>  };<br>}</pre><p><strong>Repeat<br></strong>Como o nome já diz, o repeat nos retorna uma nova string de acordo com o número de repetição informado que pode ser entre 0 e infinito:</p><pre>&quot;Bacanudos&quot;.repeat(3) // &quot;BacanudosBacanudosBacanudos&quot;</pre><p>Seu polyfill é:</p><pre>if (!String.prototype.repeat) {<br>  String.prototype.repeat = function(count) {<br>    &#39;use strict&#39;;<br>    if (this == null) {<br>      throw new TypeError(&#39;can\&#39;t convert &#39; + this + &#39; to object&#39;);<br>    }<br>    var str = &#39;&#39; + this;<br>    count = +count;<br>    if (count != count) {<br>      count = 0;<br>    }<br>    if (count &lt; 0) {<br>      throw new RangeError(&#39;repeat count must be non-negative&#39;);<br>    }<br>    if (count == Infinity) {<br>      throw new RangeError(&#39;repeat count must be less than infinity&#39;);<br>    }<br>    count = Math.floor(count);<br>    if (str.length == 0 || count == 0) {<br>      return &#39;&#39;;<br>    }    <br>    if (str.length * count &gt;= 1 &lt;&lt; 28) {<br>      throw new RangeError(&#39;repeat count must not overflow maximum string size&#39;);<br>    }<br>    var rpt = &#39;&#39;;<br>    for (var i = 0; i &lt; count; i++) {<br>      rpt += str;<br>    }<br>    return rpt;<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0LH8jqFO1kZ0OVMhkKVF9g.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3fb1b27df3c0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/allbarbos/m%C3%A9todos-bacanudos-para-string-3fb1b27df3c0">Métodos bacanudos para string</a> was originally published in <a href="https://medium.com/allbarbos">allbarbos</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>