<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Danilo Machado</title>
    <description>The latest articles on Forem by Danilo Machado (@xxdannilinxx).</description>
    <link>https://forem.com/xxdannilinxx</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%2F840213%2Fccc0a42c-b14f-4d40-8120-929674c65b72.jpeg</url>
      <title>Forem: Danilo Machado</title>
      <link>https://forem.com/xxdannilinxx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/xxdannilinxx"/>
    <language>en</language>
    <item>
      <title>Indie Hacker, faça você mesmo #1 - Use o Github Actions pra fazer os code reviews automaticamente</title>
      <dc:creator>Danilo Machado</dc:creator>
      <pubDate>Thu, 16 May 2024 00:00:12 +0000</pubDate>
      <link>https://forem.com/xxdannilinxx/indie-hacker-faca-voce-mesmo-1-use-o-github-actions-pra-fazer-os-code-reviews-automaticamente-b61</link>
      <guid>https://forem.com/xxdannilinxx/indie-hacker-faca-voce-mesmo-1-use-o-github-actions-pra-fazer-os-code-reviews-automaticamente-b61</guid>
      <description>&lt;p&gt;Um indie hacker é alguém que constrói e opera negócios de forma independente, muitas vezes focando em startups de tecnologia ou empreendimentos digitais.&lt;/p&gt;

&lt;p&gt;Eles geralmente preferem manter o controle total sobre seus projetos, evitando investimentos externos e buscando criar fontes de renda sustentáveis por conta própria.&lt;/p&gt;

&lt;p&gt;O termo "indie" vem de "independente", enquanto "hacker" refere-se à mentalidade de solucionador de problemas e à habilidade em criar soluções técnicas. Os indie hackers frequentemente compartilham suas experiências, aprendizados e estratégias dentro da comunidade, buscando colaboração e feedback para melhorar seus empreendimentos, por isso começarei uma série de posts sobre sugestões e dicas de experiências passadas que tive que podem ser úteis para outras pessoas ou outros negócios.&lt;/p&gt;

&lt;p&gt;E o primeiro assunto a ser abordado são automatizações que podemos fazer com o Github Actions pra facilitar nossa vida e otimizar nosso tempo que pode ser feito diretamente no repositório do seu projeto de forma personalizada.&lt;/p&gt;

&lt;p&gt;Podemos definir diversos tipos de trabalho pra diferentes ações, a abordada no post é pra fazer o code review do código, pois é de extrema importância manter a qualidade do código e manter padrões e as melhores práticas, mesmo que trabalhando sozinho, o que a maioria dos indie hackers fazem, ou em equipes grandes.&lt;/p&gt;

&lt;p&gt;Com o Github Actions você pode definir um fluxo de trabalho a partir de um evento, como abertura de um &lt;code&gt;PR&lt;/code&gt; por exemplo. Os fluxos de trabalho são definidos no diretório &lt;code&gt;.github/workflows&lt;/code&gt; do repositório, através de arquivos com a extensão &lt;code&gt;.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Cada fluxo de trabalho definido no arquivo &lt;code&gt;.yml&lt;/code&gt; tem uma ação que é executada por um único executor, sendo um script shell em uma máquina virtual provisionada em diversos sistemas operacionais diferentes.&lt;/p&gt;

&lt;p&gt;O exemplo que darei abaixo é estruturando um &lt;code&gt;.yml&lt;/code&gt; de acordo com a documentação, usando a linguagem &lt;code&gt;PHP&lt;/code&gt; através do &lt;code&gt;phplint&lt;/code&gt;, porém pode ser facilmente utilizado com outras linguagens, pois o &lt;a href="https://github.com/marketplace"&gt;Github Actions Marketplace&lt;/a&gt; possuí uma loja de repositórios de ações e deploys já prontos.&lt;/p&gt;

&lt;p&gt;Vamos seprar em duas partes, na parte da identificação do fluxo de trabalho e nos trabalhos em sí.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;// Opcional - O nome do fluxo de trabalho conforme aparecerá na guia "Ações" do repositório GitHub.&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PHP Linting&lt;/span&gt;

&lt;span class="s"&gt;// Especifica o evento para este fluxo de trabalho. Este exemplo usa o evento push, portanto, uma execução de fluxo de trabalho é acionada sempre que alguém envia uma alteração para o repositório ou mescla uma solicitação na branch especificada ou não.&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;master"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="s"&gt;// É usado para definir quais recursos externos à ação estão sendo acessados e como esses acessos são autorizados. Por exemplo, se uma ação precisa acessar o repositório onde está sendo executada, pode precisar de permissões para ler nos arquivos do repositório. Da mesma forma, se a ação precisa interagir com serviços externos, como fazer chamadas de API para serviços de nuvem, pode precisar de permissões específicas para isso.&lt;/span&gt;
&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Agora na definição dos trabalhos, temos a seguinte estrutura.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;// Agrupa todos os trabalhos executados no fluxo de trabalho.&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;// Configura o trabalho para ser executado na versão mais recente de um executor Ubuntu Linux. Isso significa que o trabalho será executado em uma nova máquina virtual hospedada pelo GitHub.&lt;/span&gt;
    &lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PHP Lint&lt;/span&gt;
    &lt;span class="s"&gt;runs-on&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="s"&gt;steps&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="s"&gt;// A palavra-chave uses especifica que esta etapa executará a v3 da ação actions/checkout. Esta é uma ação que faz clone do seu repositório no executor, permitindo que você execute scripts ou outras ações em seu código (como ferramentas de construção e teste). Você deve usar a ação de checkout sempre que seu fluxo de trabalho usar o código do repositório.&lt;/span&gt;
      &lt;span class="s"&gt;- name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Copying test repository&lt;/span&gt;
        &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="s"&gt;// A palavra-chave uses especifica que esta etapa executará a v8 da ação do php-lint, que irá ajudar os desenvolvedores a detectar os erros sempre que o pull request receber atualizações.&lt;/span&gt;
      &lt;span class="s"&gt;- name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run php lint&lt;/span&gt;
        &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;StephaneBour/actions-php-lint@8.0&lt;/span&gt;

      &lt;span class="s"&gt;// A palavra-chave uses especifica que esta etapa executará a v1 da ação do review dog, que irá ajudar os desenvolvedores a detectar e corrigir erros de codificação adicionando comentários no pull requests.&lt;/span&gt;
      &lt;span class="s"&gt;- name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run php check code with reviewdog&lt;/span&gt;
        &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GeneaLabs/action-reviewdog-phpstan@1.1.2&lt;/span&gt;
        &lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error"&lt;/span&gt;
          &lt;span class="na"&gt;fail_on_error&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
          &lt;span class="na"&gt;phpstan_level&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
          &lt;span class="na"&gt;reporter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;github-pr-review"&lt;/span&gt;
          &lt;span class="na"&gt;target_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;O resultado do nosso fluxo de trabalho seria algo parecido com isso:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;A revisão de código pode ajudar a identificar potenciais vulnerabilidades de segurança no código antes que ele seja implantado em produção. Isso é especialmente importante em ambientes onde a segurança é uma preocupação primordial.&lt;/p&gt;

&lt;p&gt;Após o início de uma execução de fluxo de trabalho, você pode ver um gráfico de visualização do progresso da execução e visualizar a atividade de cada etapa em GitHub. &lt;/p&gt;

&lt;p&gt;O GitHub Actions pode ajudá-lo a automatizar quase todos os aspectos dos processos de desenvolvimento da sua aplicação. Pronto para começar?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fontes&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.github.com/pt/actions"&gt;Github Actions - Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>indiehacker</category>
      <category>buildinpublic</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Introdução aos testes unitários em Go</title>
      <dc:creator>Danilo Machado</dc:creator>
      <pubDate>Fri, 13 Jan 2023 13:23:56 +0000</pubDate>
      <link>https://forem.com/xxdannilinxx/introducao-aos-testes-unitarios-em-go-4cjb</link>
      <guid>https://forem.com/xxdannilinxx/introducao-aos-testes-unitarios-em-go-4cjb</guid>
      <description>&lt;p&gt;Os testes unitários são testes que verificam se uma parte específica do código, costumeiramente a nível de função, está funcionando corretamente. Em um ambiente orientado a objetos é usualmente a nível de classes e a mínima unidade de testes inclui construtores e destrutores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Por qual motivo devo realizar testes unitários na minha aplicação?&lt;/strong&gt;&lt;br&gt;
Mas o verdadeiro propósito do teste unitário é fornecer-lhe feedback quase instantâneo sobre o projeto e a implementação de seu código. A criação de testes unitários, ou melhor, a facilidade ou dificuldade com que você pode criá-los lhe diz exatamente o quão testável é seu código. O quão bem você o projetou.&lt;/p&gt;

&lt;p&gt;No nosso exemplo, vamos simular um teste unitário em uma função que faz a validação de um symbol de criptomoedas bem simples mas que foi retirado de produção.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Todo o teste unitário necessita de um planejamento prévio. Deve ser de entendimento do desenvolvedor os requisitos que aquela funcionalidade tem que cobrir, qual a sua entrada e qual a sua saída e como se processa o fluxo interno dos dados. Logo, nesse primeiro momento, podemos observar a função e notar que existem dois cenários que não podem faltar, sendo ele o cenário de sucesso e o cenário de falha. Pra isso usaremos a lib mais utilizada que é a &lt;a href="https://github.com/stretchr/testify" rel="noopener noreferrer"&gt;testify.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na documentação do testify tem alguns exemplos, seguindo os cenários de teste unitário que definimos para nossa função, o código iniciaria parecido com esse.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Para testar nosso cenário de falha, basta chamarmos nossa função passando um parâmetro inválido sem a barra e comparar se o erro vindo da função é igual ao erro que definimos para ela.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;E no caso do sucesso, basta validarmos que a função não retorne erro, por passar o parâmetro adequadamente.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Digite &lt;code&gt;go test -p 1 -covermode=atomic -tags=unit&lt;/code&gt; para rodar os testes unitários ou use os atalhos do vscode, caso utilize. Você deverá visualizar o retorno com algo parecido a isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== RUN   TestValidationSymbol
=== RUN   TestValidationSymbol/Cenário_1_-_Falha
=== RUN   TestValidationSymbol/Cenário_1_-_Sucesso
--- PASS: TestValidationSymbol (0.00s)
    --- PASS: TestValidationSymbol/Cenário_1_-_Falha (0.00s)
    --- PASS: TestValidationSymbol/Cenário_1_-_Sucesso (0.00s)
PASS
ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Claro, essa é só uma introdução, a lib testify tem diversas validações que facilitam a implementação de testes unitários no dia-a-dia, em produção usamos em coisas mais complexas como validar métodos que retornam dados do banco de dados, métodos que fazem validações, métodos responsáveis por gerenciar endpoints e até mesmo com essa lib, conseguimos fazer os testes de integração, que seria um outro assunto.&lt;/p&gt;

&lt;p&gt;Lembre-se, sempre que alterar um método ou função, você deve também alterar o teste unitário, pra isso, temos algumas formas de facilitar a checagem dos testes para verificar se teve alguma alteração, criando um atalho no &lt;code&gt;Makefile&lt;/code&gt; por exemplo e chamando na pipeline do repositório ou até mesmo rodando localmente antes de subir sua branch.&lt;/p&gt;

&lt;p&gt;Para rodar o comando do exemplo, basta digitar: &lt;code&gt;make run-test&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;É isso. Recomendo a leitura também de artigos sobre criação de mocks, pois muitas das vezes irá precisar de mocks para realizar testes unitários, um exemplo são chamadas de outros serviços, elas precisarão ser feitas via mock.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Melhorando a perfomace de projetos PHP com Memcached</title>
      <dc:creator>Danilo Machado</dc:creator>
      <pubDate>Thu, 11 Aug 2022 19:26:00 +0000</pubDate>
      <link>https://forem.com/xxdannilinxx/melhorando-a-perfomace-de-projetos-php-com-memcached-2gfo</link>
      <guid>https://forem.com/xxdannilinxx/melhorando-a-perfomace-de-projetos-php-com-memcached-2gfo</guid>
      <description>&lt;p&gt;O módulo Memcached fornece uma interface processual e orientada a objetos útil para o daemon de armazenamento em cache do memcached altamente eficaz, que foi especialmente projetado para diminuir a carga do banco de dados em aplicativos da Web dinâmicos.&lt;/p&gt;

&lt;p&gt;O módulo Memcached também fornece um manipulador de sessão (memcache).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dicas de onde usar Memcached na sua aplicação?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dashboards&lt;/li&gt;
&lt;li&gt;Listagens &lt;/li&gt;
&lt;li&gt;Consultas&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O principal ponto do Memcached é que, ele diminui o tempo de resposta de suas páginas web, o que, em troca, melhora a experiência geral do cliente. Um melhor tempo de resposta permite que os usuários busquem dados perfeitamente.&lt;/p&gt;

&lt;p&gt;Você pode verificar se já está instalado no seu servidor, através do phpinfo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nb"&gt;phpinfo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Caso não esteja instalado ainda, basta seguir os passos abaixo.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;memcached
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;memcached
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;OBS: O módulo Memcached 3.0.8 não funciona com o php 7 (ou superior).&lt;/p&gt;

&lt;p&gt;Um exemplo de conexão, para verificar se o Memcached está funcionando adequadamente.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;A partir do exemplo de conexão, você pode criar funções inteligentes para consumir o cache e preencher o cache com informações atualizadas. O objetivo é obter informações sem precisar consultar o banco de dados. Somente se as informações não estiverem cacheadas iremos consultar a banco de dados e após armazenar as informações em cache para as futuras consultas.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Empresas que usam o Memcached&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://shopify.com"&gt;shopify.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://apple.com"&gt;apple.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://walmart.com"&gt;walmart.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com o Memcached podemos arquitetar excelentes projetos com estruturas de cache em memória RAM utilizando diversos servidores. É recomendado salvar apenas as informações mais importantes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fontes&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://php.net"&gt;php.net&lt;/a&gt;&lt;br&gt;
&lt;a href="https://memcached.org"&gt;memcached.org&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>cache</category>
      <category>performance</category>
    </item>
    <item>
      <title>Implementando grandes dependências no AWS Lambda através do AWS Layer</title>
      <dc:creator>Danilo Machado</dc:creator>
      <pubDate>Sun, 03 Apr 2022 16:27:06 +0000</pubDate>
      <link>https://forem.com/xxdannilinxx/implementando-grandes-dependencias-no-aws-lambda-atraves-do-aws-layer-19k</link>
      <guid>https://forem.com/xxdannilinxx/implementando-grandes-dependencias-no-aws-lambda-atraves-do-aws-layer-19k</guid>
      <description>&lt;p&gt;Hoje irei falar um pouco desse serviço da AWS pouco utilizado, pois eu precisava implementar em um lambda algumas libs que somavam mais de 500 MB juntas, e obviamente não conseguia fazer o deploy, devido a limitação de 250 MB da AWS e tive que pesquisar bastante para solucionar o impasse.&lt;/p&gt;

&lt;p&gt;Então descobri esse serviço, que você pode provisionar as dependências em layers (camadas) e especificar em qual lambda quer usar, podendo ser utilizado por vários lambdas simultaneamente. O uso de camadas reduz o tamanho dos arquivos de implantação carregados e agiliza a implantação do seu código.&lt;/p&gt;

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

&lt;p&gt;Imagine que você precise desenvolver um lambda para declarar imposto de rendas e nesse lambda, precisa conter três dependência do node: express, sequelize e mysql. &lt;/p&gt;

&lt;p&gt;No meu exemplo utilizo node, mas o AWS Layer funciona em todas as linguagens em que a AWS dão suporte, continuando nosso exemplo, vamos supor que o express tem 100 MB, sequelize 100 MB e mysql 100 MB deszipados após o build da node_modules, logo o lambda não irá fazer deploy, pela limitação de 250 MB.&lt;/p&gt;

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

&lt;p&gt;Para resolver esse problema, utiliza-se o AWS Layer, a solução seria criar um layer pro express, um layer pro sequelize e um layer pro mysql separadamente, como se fosse uma dependência do npm. Nas configurações do lambda, você declara o layer como dependência, como disse anteriormente, podendo ser utilizado por diversos lambdas, lembrando que cada layer também tem a limitação de 250 MB e pode ser versionado.&lt;/p&gt;

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

&lt;p&gt;Esses casos de pacotes grandes são bem raros, mas quando precisei, essa foi a solução.  A AWS não cobra pelos layers, somente é cobrado o valor dos lambdas por execução. Você pode criar layers usando o console do Lambda, a API do Lambda, o AWS CloudFormation ou o AWS Serverless Application Model (AWS SAM). Para obter mais informações sobre como criar os layers consulte a documentação da AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html"&gt;Layer - AWS Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Guia: Trabalhando com pdfs na AWS através do Node.js</title>
      <dc:creator>Danilo Machado</dc:creator>
      <pubDate>Fri, 01 Apr 2022 12:33:26 +0000</pubDate>
      <link>https://forem.com/xxdannilinxx/guia-trabalhando-com-pdfs-na-aws-3pa5</link>
      <guid>https://forem.com/xxdannilinxx/guia-trabalhando-com-pdfs-na-aws-3pa5</guid>
      <description>&lt;p&gt;Depois de apanhar bastante tentando realizar tarefas que envolviam pdf na AWS, deixo esse guia para quem precisar realizar esse tipo de demanda.&lt;/p&gt;

&lt;p&gt;No meu caso, eu precisava fazer em node, então todas as bibliotecas e features que usei, são em javascript.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Primeira pergunta a se fazer, o serviço é um AWS Lambda/Batch ou ECS?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Lambda/Batch
&lt;/h3&gt;

&lt;p&gt;Recomendo usar a biblioteca &lt;a href="https://www.npmjs.com/package/puppeteer"&gt;puppeteer&lt;/a&gt; na &lt;code&gt;versão 8 do node&lt;/code&gt;, pois as versões mais atualizadas são mais pesadas e a AWS limita o tamanho do lambda em &lt;code&gt;250mbs&lt;/code&gt;. Outra opção seria criar um layer na AWS Layer.&lt;/p&gt;

&lt;p&gt;O puppetter utiliza o chromium para realizar as impressões e é bem fácil utilizar. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Dá pra imprimir páginas da web e templates em html montado através do &lt;a href="https://www.npmjs.com/package/handlebars"&gt;handlebars&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  ECS
&lt;/h3&gt;

&lt;p&gt;Já no ECS, recomendo a utilização do &lt;a href="https://www.npmjs.com/package/html-pdf?activeTab=readme"&gt;html-pdf&lt;/a&gt; na &lt;br&gt;
 &lt;code&gt;versão ^8.0.0 do node&lt;/code&gt;, por ser mais leve e funcionar bem. Ele utiliza o phantomjs, que não funciona no AWS Lambda e Batch;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  2) Precisa encryptar, colocar senha no pdf?
&lt;/h2&gt;

&lt;p&gt;Sem dúvidas, a melhor opção pra encryptar os pdfs, atribuir senhas de user e owner é o &lt;a href="https://www.npmjs.com/package/hummus-recipe"&gt;hummus-recipe&lt;/a&gt;, ele precisa rodar na &lt;code&gt;versão &amp;gt;=14.0.0&lt;/code&gt; do node para funcionar.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Ele funciona muito bem em qualquer serviço da AWS. &lt;/p&gt;

&lt;p&gt;Mas se por algum acaso não conseguir utilizar o hummus-recipe para encrypt, devido a versão do node ser inferior a &lt;code&gt;14.0.0&lt;/code&gt;,  outro bom pacote é o &lt;a href="https://www.npmjs.com/package/node-qpdf"&gt;qpdf&lt;/a&gt;. Será preciso copiar os &lt;a href="https://github.com/qpdf/qpdf/releases"&gt;arquivos binários do qpdf&lt;/a&gt; para o container através do Dockerfile para executar o qpdf.&lt;/p&gt;

&lt;p&gt;Agora é só subir o pdf pro S3 e ser feliz!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>QZ Tray: Impressão em impressoras térmicas pelo navegador com Javascript</title>
      <dc:creator>Danilo Machado</dc:creator>
      <pubDate>Fri, 01 Apr 2022 02:12:38 +0000</pubDate>
      <link>https://forem.com/xxdannilinxx/qz-tray-impressao-em-impressoras-termicas-pelo-navegador-1mam</link>
      <guid>https://forem.com/xxdannilinxx/qz-tray-impressao-em-impressoras-termicas-pelo-navegador-1mam</guid>
      <description>&lt;p&gt;Neste artigo irei abordar a melhor maneira de imprimir em impressoras térmicas direto pelo navegador.&lt;/p&gt;

&lt;p&gt;A solução do QZ é utilizada pela grande maioria de softwares do ramo de cardápio digital no Brasil.&lt;/p&gt;

&lt;p&gt;Apesar do QZ vender licenças para domínios, ele é um open sourcer. Ou seja, precisamos alterar o código fonte do QZ e compilar novamente, de acordo com o nosso domínio.&lt;/p&gt;

&lt;p&gt;1) Você pode realizar os testes direto no &lt;a href="https://demo.qz.io/" rel="noopener noreferrer"&gt;demonstrativo do QZ&lt;/a&gt;;&lt;/p&gt;

&lt;p&gt;2) Ao realizar os testes, você verá os pop-ups do QZ aparecendo igual na imagem abaixo, informando sobre a licença. Por isso precisaremos recompilar o QZ com seu novo certificado.&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%2Fch2zydom73zjysxyni2r.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%2Fch2zydom73zjysxyni2r.png" alt="qz sem licença"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) Recomendo realizar o download do &lt;a href="https://www.oracle.com/java/technologies/downloads/" rel="noopener noreferrer"&gt;JDK 7&lt;/a&gt; ou superior, &lt;a href="https://ant.apache.org/" rel="noopener noreferrer"&gt;Apache Ant&lt;/a&gt; e Open SSL;&lt;/p&gt;

&lt;p&gt;4) Faça o clone do repositório do &lt;a href="https://github.com/qzind/tray" rel="noopener noreferrer"&gt;QZ Tray no github&lt;/a&gt;;&lt;/p&gt;

&lt;p&gt;5) Gere o certificado ssl com o Open SSL;&lt;/p&gt;

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

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 11499 -nodes


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

&lt;/div&gt;
&lt;p&gt;&lt;em&gt;OBS: quando perguntar o dominio, colocar o curinga, ex: *.seusite.com.br&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;6) Gere a private key usando o certificado ssl;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

openssl pkcs12 -inkey key.pem -in cert.pem -export -out privateKey.pfx


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

&lt;/div&gt;
&lt;p&gt;7) Coloque o arquivo &lt;code&gt;key.pem&lt;/code&gt; gerado anteriormente na pasta do &lt;code&gt;tray-master&lt;/code&gt;, na raíz, que foi clonado do github;&lt;/p&gt;

&lt;p&gt;8) Agora, precisamos compilar o QZ com o Apache Ant, mas antes, lembre-se;&lt;/p&gt;

&lt;p&gt;8.1) Depois de baixar o Apache Ant, coloque a pasta na variável de ambiente;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- ANT_HOME=caminho
- Path=[]caminho


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

&lt;/div&gt;
&lt;p&gt;8.2) Rodar o comando para compilar de acordo com seu sistema operacional;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// win
ant nsis -Dauthcert.use="key.pem"

// linux
ant makeself -Dauthcert.use="key.pem"

// mac
ant pkgbuild -Dauthcert.use="key.pem"


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

&lt;/div&gt;
&lt;p&gt;9) Depois de compilado, abrir QZ em &lt;code&gt;/tray-master/out/dist/qz-tray.jar&lt;/code&gt; e clicar em "+", pra gerar o certificado, será gerado o &lt;code&gt;digital-certificate.txt&lt;/code&gt; e &lt;code&gt;private-key.pem&lt;/code&gt;, copie os 2 e coloque no seu servidor, pro sistema poder utilizar os certificados;&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%2Fi9nc2g3xtkim1eqc39pd.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%2Fi9nc2g3xtkim1eqc39pd.png" alt="gerando key"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10) E quando for usar o QZ no seu website, basta utilizar os certificados gerados;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;11) E o seu arquivo sign-message.php pode ser montado da seguinte forma;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;12) Depois disso tudo, os pop-ups do QZ irão parar de aparecer e você irá conseguir imprimir sem problemas;&lt;/p&gt;

&lt;p&gt;13) Não esqueça de dar uma olhada na &lt;a href="https://qz.io/wiki/getting-started" rel="noopener noreferrer"&gt;documentação do QZ&lt;/a&gt;, pois lá tem todas as configurações e opções de impressão; &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>print</category>
    </item>
    <item>
      <title>Exemplos de uso da api do cpanel</title>
      <dc:creator>Danilo Machado</dc:creator>
      <pubDate>Thu, 31 Mar 2022 23:53:19 +0000</pubDate>
      <link>https://forem.com/xxdannilinxx/exemplos-de-uso-da-api-do-cpanel-1me0</link>
      <guid>https://forem.com/xxdannilinxx/exemplos-de-uso-da-api-do-cpanel-1me0</guid>
      <description>&lt;p&gt;Bom, quando trabalhei num sistema distribuído, precisávamos criar subdomínios, databases e várias outras coisas em real-time para cada cliente especificamente, então criei um shell script para automatizar as tarefas.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Deixo acima alguns endpoints da versão v2 da api do cpanel que me ajudou bastante na automatização.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://api.docs.cpanel.net/cpanel/introduction"&gt;cpanel api docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>shel</category>
      <category>cpanel</category>
    </item>
  </channel>
</rss>
