<?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: Jeferson Guedes</title>
    <description>The latest articles on DEV Community by Jeferson Guedes (@jefersonguedes).</description>
    <link>https://dev.to/jefersonguedes</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%2F63233%2F1ca2651d-769e-4597-903e-a26f646643c6.jpg</url>
      <title>DEV Community: Jeferson Guedes</title>
      <link>https://dev.to/jefersonguedes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jefersonguedes"/>
    <language>en</language>
    <item>
      <title>PHP-FPM/JIT vs FrankenPHP Worker vs Swoole: um benchmark honesto com Symfony</title>
      <dc:creator>Jeferson Guedes</dc:creator>
      <pubDate>Tue, 09 Jun 2026 16:55:20 +0000</pubDate>
      <link>https://dev.to/jefersonguedes/php-fpmjit-vs-frankenphp-worker-vs-swoole-um-benchmark-honesto-com-symfony-2l8f</link>
      <guid>https://dev.to/jefersonguedes/php-fpmjit-vs-frankenphp-worker-vs-swoole-um-benchmark-honesto-com-symfony-2l8f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — Para CPU puro, o que importa é o JIT, e FPM empata com FrankenPHP. Para leitura, os runtimes persistentes voam (até &lt;strong&gt;3,5×&lt;/strong&gt; o FPM). Para escrita, FrankenPHP lidera, mas o Swoole expõe contenção de conexão. E o erro mais comum em benchmark de runtime é comparar configurações com &lt;strong&gt;número de workers diferente&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Por que fiz isso
&lt;/h2&gt;

&lt;p&gt;Toda discussão sobre "PHP moderno é rápido" esbarra na mesma confusão: as pessoas comparam &lt;strong&gt;runtimes&lt;/strong&gt; (FPM, FrankenPHP, Swoole) mas mudam dezenas de variáveis ao mesmo tempo — versão do PHP, JIT ligado/desligado, número de processos, framework, banco. O resultado é inconclusivo.&lt;/p&gt;

&lt;p&gt;A proposta aqui foi isolar a variável &lt;strong&gt;runtime&lt;/strong&gt;: o &lt;strong&gt;mesmo&lt;/strong&gt; código Symfony, o &lt;strong&gt;mesmo&lt;/strong&gt; PHP 8.4 com Opcache + JIT, o &lt;strong&gt;mesmo&lt;/strong&gt; MySQL 8, mudando só &lt;em&gt;como o PHP é executado&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Os três cenários
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Arquitetura&lt;/th&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;th&gt;Porta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Clássico tunado&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Nginx + PHP-FPM&lt;/strong&gt; (Opcache + JIT &lt;code&gt;1255&lt;/code&gt;, Unix socket)&lt;/td&gt;
&lt;td&gt;8081&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Moderno worker&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Traefik + FrankenPHP&lt;/strong&gt; (Worker Mode)&lt;/td&gt;
&lt;td&gt;8182*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Assíncrono&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Traefik + Swoole&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8083&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;* A &lt;code&gt;:8082&lt;/code&gt; original estava ocupada por um processo local na minha máquina, então o FrankenPHP foi publicado na 8182.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Todos compartilham o mesmo &lt;code&gt;app/&lt;/code&gt; Symfony — o que muda é só a imagem Docker e o modo de execução. Endpoints de teste:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /bench/cpu-bound&lt;/code&gt; — contagem de primos + hashes bcrypt (CPU puro, sensível ao JIT)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /bench/io-read&lt;/code&gt; — &lt;code&gt;SELECT&lt;/code&gt; dos 20 registros mais recentes → &lt;code&gt;JsonResponse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /bench/io-write&lt;/code&gt; — &lt;code&gt;INSERT&lt;/code&gt; + &lt;code&gt;flush()&lt;/code&gt;, devolve o ID gerado&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A pegadinha que quase invalidou tudo
&lt;/h2&gt;

&lt;p&gt;Na &lt;strong&gt;primeira&lt;/strong&gt; rodada, os workers estavam desbalanceados: FPM com &lt;code&gt;pm.max_children=16&lt;/code&gt; e FrankenPHP/Swoole com 4 workers cada. Resultado "de fábrica":&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;FPM (16w)&lt;/th&gt;
&lt;th&gt;FrankenPHP (4w)&lt;/th&gt;
&lt;th&gt;Swoole (4w)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;io-read&lt;/td&gt;
&lt;td&gt;1.654&lt;/td&gt;
&lt;td&gt;4.085&lt;/td&gt;
&lt;td&gt;4.099&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;io-write&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;919&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;680&lt;/td&gt;
&lt;td&gt;644&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cpu-bound&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;27&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Parece que o FPM "ganha" em escrita e CPU — mas isso é &lt;strong&gt;viés de paralelismo&lt;/strong&gt;: com 64 conexões batendo numa tarefa de CPU, o FPM processa 16 em paralelo e os outros só 4. Não é o runtime, é a contagem de processos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lição:&lt;/strong&gt; num benchmark de runtime, iguale o número de workers. Senão você está medindo &lt;code&gt;pm.max_children&lt;/code&gt;, não a arquitetura.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O comparativo justo (4 workers em todos)
&lt;/h2&gt;

&lt;p&gt;Baixei o FPM para &lt;code&gt;pm.max_children=4&lt;/code&gt; e repeti — 64 conexões concorrentes, 12s por medição, com warmup descartado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Famgfxoip8t1fgc14qoyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Famgfxoip8t1fgc14qoyy.png" alt="Throughput por endpoint (req/s)" width="799" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fd22jc82ho84vac8xvg84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fd22jc82ho84vac8xvg84.png" alt="Latência p99 por endpoint (ms)" width="799" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fv8d0txsst7bx7bk3epm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fv8d0txsst7bx7bk3epm8.png" alt="Speedup vs PHP-FPM" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Throughput (req/s — maior é melhor)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;FPM+JIT&lt;/th&gt;
&lt;th&gt;FrankenPHP&lt;/th&gt;
&lt;th&gt;Swoole&lt;/th&gt;
&lt;th&gt;Vencedor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;cpu-bound&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;19,7&lt;/td&gt;
&lt;td&gt;19,7&lt;/td&gt;
&lt;td&gt;14,4&lt;/td&gt;
&lt;td&gt;empate FPM/FrankenPHP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;io-read&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.144&lt;/td&gt;
&lt;td&gt;3.262&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.066&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Swoole&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;io-write&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;268&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;513&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;230&lt;/td&gt;
&lt;td&gt;FrankenPHP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Latência p99 (ms — menor é melhor)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;FPM+JIT&lt;/th&gt;
&lt;th&gt;FrankenPHP&lt;/th&gt;
&lt;th&gt;Swoole&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;cpu-bound&lt;/td&gt;
&lt;td&gt;3.467&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.334&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;9.205&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;io-read&lt;/td&gt;
&lt;td&gt;205&lt;/td&gt;
&lt;td&gt;210&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;92&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;io-write&lt;/td&gt;
&lt;td&gt;506&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;364&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.182&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Speedup vs FPM
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;FrankenPHP&lt;/th&gt;
&lt;th&gt;Swoole&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;cpu-bound&lt;/td&gt;
&lt;td&gt;1,00×&lt;/td&gt;
&lt;td&gt;0,73×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;io-read&lt;/td&gt;
&lt;td&gt;2,85×&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3,55×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;io-write&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,91×&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0,86×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  O que os números dizem
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. CPU puro → é o JIT, e ele empata.&lt;/strong&gt; FPM e FrankenPHP têm o mesmo JIT (&lt;code&gt;opcache.jit=1255&lt;/code&gt;, buffer 128M) e deram &lt;strong&gt;exatamente&lt;/strong&gt; o mesmo número (19,7 req/s). Faz sentido: a economia de &lt;em&gt;boot&lt;/em&gt; do worker não ajuda quando o tempo é gasto &lt;strong&gt;computando&lt;/strong&gt;, não inicializando. O Swoole ficou atrás por overhead do seu reactor no caminho síncrono.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Leitura → runtimes persistentes voam.&lt;/strong&gt; Swoole &lt;strong&gt;3,55×&lt;/strong&gt; e FrankenPHP &lt;strong&gt;2,85×&lt;/strong&gt; o FPM. Aqui o que domina é o reúso do container de injeção de dependência do Symfony e o &lt;em&gt;zero bootstrap&lt;/em&gt; por request — o FPM paga esse pedágio em toda requisição. Swoole ainda leva o melhor p99 (92ms).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Escrita → FrankenPHP brilha, Swoole sofre.&lt;/strong&gt; FrankenPHP fez &lt;strong&gt;1,9×&lt;/strong&gt; o FPM e teve o melhor p99. Já o Swoole &lt;strong&gt;degradou&lt;/strong&gt; (p99 de &lt;strong&gt;1.182ms&lt;/strong&gt;) — é o sintoma clássico de &lt;strong&gt;contenção nas conexões persistentes&lt;/strong&gt; com poucos workers no caminho de escrita. Foi exatamente o que o teste de &lt;code&gt;io-write&lt;/code&gt; foi desenhado pra expor: no FPM a conexão abre/fecha por request; no Swoole/FrankenPHP ela persiste por worker e precisa ser gerenciada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tropeços de setup que valem registrar
&lt;/h2&gt;

&lt;p&gt;Montar isso em PHP 8.4 + Docker novo (2026) rendeu alguns perrengues que podem te poupar tempo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Composer bloqueando por advisory.&lt;/strong&gt; O Composer atual recusa versões com &lt;em&gt;security advisory&lt;/em&gt; na resolução. Vários advisories recentes do Symfony cobrem toda a linha 7.x — desliguei com &lt;code&gt;config.policy.advisories.block=false&lt;/code&gt; (PoC local).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensão &lt;code&gt;zip&lt;/code&gt; faltando.&lt;/strong&gt; Sem &lt;code&gt;zip&lt;/code&gt;/&lt;code&gt;unzip&lt;/code&gt;, o &lt;code&gt;composer install&lt;/code&gt; falha ao extrair os pacotes. Adicionei &lt;code&gt;zip&lt;/code&gt; via &lt;code&gt;install-php-extensions&lt;/code&gt; nas três imagens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;symfony/var-exporter&lt;/code&gt; 8.x vs Doctrine ORM 3.&lt;/strong&gt; O ORM precisa do &lt;code&gt;LazyGhost&lt;/code&gt; da &lt;code&gt;var-exporter&lt;/code&gt; 6.4/7; a 8.x removeu o trait. Fixei em &lt;code&gt;7.2.*&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controller sem &lt;code&gt;controller.service_arguments&lt;/code&gt;.&lt;/strong&gt; Controller "plano" (sem &lt;code&gt;AbstractController&lt;/code&gt;) não recebe injeção em argumentos de action — precisei taggear no &lt;code&gt;services.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traefik + Docker socket.&lt;/strong&gt; O daemon novo exige API ≥ 1.40 e o provider Docker do Traefik v3.2 negocia 1.24 → quebra. Troquei para o &lt;strong&gt;file provider&lt;/strong&gt; (config estática), roteando por nome de container. Mais robusto e sem depender do socket.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Como reproduzir
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# subir o ambiente&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--build&lt;/span&gt;

&lt;span class="c"&gt;# rodar a matriz (Python + aiohttp) e salvar CSV/JSON&lt;/span&gt;
./.venv/bin/python bench/loadtest.py &lt;span class="nt"&gt;-d&lt;/span&gt; 12 &lt;span class="nt"&gt;-c&lt;/span&gt; 64 &lt;span class="nt"&gt;-w&lt;/span&gt; 4

&lt;span class="c"&gt;# gerar os gráficos comparativos a partir do resultado&lt;/span&gt;
./.venv/bin/python bench/plot_results.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Código completo (Dockerfiles, configs, gerador de carga e notebook) no GitHub: &lt;a href="https://github.com/jeferson-guedes/bench-php-vanilla-vs-modern" rel="noopener noreferrer"&gt;jeferson-guedes/bench-php-vanilla-vs-modern&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Veredito
&lt;/h2&gt;

&lt;p&gt;Não existe "runtime mais rápido". Existe &lt;strong&gt;runtime certo para a carga&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;App I/O-bound de leitura&lt;/strong&gt; (APIs, dashboards): Swoole ou FrankenPHP — ganho real de 3×.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escrita concorrente&lt;/strong&gt;: FrankenPHP, com atenção ao &lt;em&gt;pooling&lt;/em&gt;; Swoole exige tunar workers × conexões.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU-bound&lt;/strong&gt;: ligue o JIT e durma tranquilo — FPM clássico segura o tranco igual.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O ganho dos runtimes modernos é &lt;strong&gt;arquitetural&lt;/strong&gt; (estado persistente, sem bootstrap), não mágico. Onde não há bootstrap a economizar, o bom e velho FPM com JIT continua competitivo — e muito mais simples de operar.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Ambiente: PHP 8.4, Symfony 7.2, Doctrine ORM 3, MySQL 8, Docker 29.4 no macOS. Carga: 64 conexões, 12s/medição, 4 workers por runtime. Números são de uma única rodada local — para conclusões de produção, rode várias vezes e descarte a primeira.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;▎ 💬 Achou um furo na metodologia? Tem caso, config ou runtime que ficou de fora? Comenta aí — quero transformar isto num guia definitivo sobre a melhor abordagem em PHP, e quanto mais gente questionar os números.&lt;/p&gt;

</description>
      <category>php</category>
      <category>frankenphp</category>
      <category>swoole</category>
      <category>fpm</category>
    </item>
    <item>
      <title>PHP Modificando propriedade privada sem modificadores</title>
      <dc:creator>Jeferson Guedes</dc:creator>
      <pubDate>Thu, 19 Jan 2023 23:31:21 +0000</pubDate>
      <link>https://dev.to/jefersonguedes/php-modificando-propriedade-privada-sem-modificadores-3ach</link>
      <guid>https://dev.to/jefersonguedes/php-modificando-propriedade-privada-sem-modificadores-3ach</guid>
      <description>&lt;h2&gt;
  
  
  Apresentação
&lt;/h2&gt;

&lt;p&gt;Fala pessoal tudo bem !? A ideia deste artigo é ajudar vocês a contribuir mais com testes dentro da empresa&lt;/p&gt;

&lt;p&gt;Vamos a seguinte hipótese imagina que te peçam para testar uma classe inchada cheio de classes e um alto acoplamento e claro essa classe não tem as propriedade sendo recebidas por construtor o que vocês&lt;/p&gt;

&lt;p&gt;Classe exemplo:&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="kn"&gt;use&lt;/span&gt; &lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeClass&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;AnotherClass&lt;/span&gt; &lt;span class="nv"&gt;$anotherClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;anotherClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AnotherClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;//... another calls classes&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;someMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;SomeType&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//... any business logic &lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;anotherClass&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;doIt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$someType&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;Pensam comigo terá um alto acoplamento e se for aceitar que essa classe seja enviada por parâmetro no seu construtor possa ser que quebre compatibilidade com outras classes que podem estar usando.&lt;/p&gt;

&lt;p&gt;Imagina que &lt;code&gt;anotherClass::doIt&lt;/code&gt; seja algo arriscado que se for chamado possa ter uma consequência grave por exemplo um update em massa para resolver esse problema você pode sobreescrever essa propriedade no seu test:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeTest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testAnywere&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$anotherClassMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMockBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AnotherClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&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;disableOriginalConstructor&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;getMock&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$anotherClassMock&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'doIt'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$someClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SomeClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$setSomeClassClosure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$anotherClassMock&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;anotherClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$anotherClassMock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="nv"&gt;$doSetSomeClassClosure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$setSomeClassClosure&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;bindTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$someClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SomeClass&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$doSetSomeClassClosure&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;&lt;strong&gt;Obs: A ideia desta forma de testar é te dar poder para conseguir resolver algo legado e bastante arriscado, no geral o ideal seria uma reescrita deste método&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>symfony</category>
      <category>think</category>
      <category>tdd</category>
    </item>
    <item>
      <title>Crie um servidor PHP + API Rest + GraphQL</title>
      <dc:creator>Jeferson Guedes</dc:creator>
      <pubDate>Tue, 28 Jun 2022 19:36:50 +0000</pubDate>
      <link>https://dev.to/jefersonguedes/crie-um-servidor-php-api-rest-graphql-15d6</link>
      <guid>https://dev.to/jefersonguedes/crie-um-servidor-php-api-rest-graphql-15d6</guid>
      <description>&lt;h3&gt;
  
  
  Contextualização:
&lt;/h3&gt;

&lt;p&gt;Vamos construir um servidor GraphQL + RestFull escrito em ApiPlatform, este projeto irá te ajudar a entender um  sobre a facilidade de construir uma API Rest e GraphQL no mesmo projeto.&lt;/p&gt;

&lt;p&gt;Para este tutorial eu desenvolvi uma lista de itens a serem pagos para um planejamento de casamento.&lt;/p&gt;

&lt;p&gt;A ideia deste projeto é bem simples casal tem 0::N eventos cada evento tem um nome e valor.&lt;/p&gt;

&lt;p&gt;Bom, chega de conversa e vamos para o código:&lt;/p&gt;

&lt;h3&gt;
  
  
  Pré requisitos:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker + Docker Compose&lt;/li&gt;
&lt;li&gt;PHP 8.1&lt;/li&gt;
&lt;li&gt;Composer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Instalação:
&lt;/h3&gt;

&lt;p&gt;Abra um terminal e crie um diretório onde você deseja que seu código fique em seu computador.&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;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;wedding
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;wedding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso seu projeto Symfony será criado, execute passo a passo.&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;composer create-project symfony/skeleton:&lt;span class="s2"&gt;"6.1.*"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;composer req orm &lt;span class="c"&gt;# y para criar o docker-compose.yml&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;composer req api
&lt;span class="nv"&gt;$ &lt;/span&gt;composer require webonyx/graphql-php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suba seu container com banco de dados configurado&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;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos criar nossas entidades, mas antes precisamos criar uma dependência de desenvolvimento&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;composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; symfony/maker-bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entidade &lt;code&gt;Couple&lt;/code&gt;, em seu terminal digite:&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;php bin/console make:entity Couple
manName: &amp;lt;string:255&amp;gt; not null
womanName: &amp;lt;string:255&amp;gt; not null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Siga com os nomes como no print:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq3bysmgpnifo20xe7kj.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%2Feq3bysmgpnifo20xe7kj.png" alt="Entity Couple"&gt;&lt;/a&gt;&lt;br&gt;
Entidade &lt;code&gt;Event&lt;/code&gt;, em seu terminal digite:&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;php bin/console make:entity Event
name: &amp;lt;string:255&amp;gt; not null
price: &amp;lt;float&amp;gt; not null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos voltar para a criação de entidade, mas vamos só criar uma relação 0::N de Couple com Events&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;php bin/console make:entity Couple
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fjplpst0o1kqa0aszgcym.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%2Fjplpst0o1kqa0aszgcym.png" alt="Relation with events"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No mapeamento da classe Event você precisará ajustar na mão o relacionamento, deve ficar assim:&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="c1"&gt;#src/Entity/Event.php&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;
    &lt;span class="na"&gt;#[ORM\ManyToOne(targetEntity: Couple::class)]&lt;/span&gt;
    &lt;span class="na"&gt;#[ORM\JoinColumn(name: "couple_id", referencedColumnName: "id", nullable: true)]&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$couple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos gerar nossa migrações, no seu e subir a estrutura de SQL.&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;php bin/console make:migration
&lt;span class="nv"&gt;$ &lt;/span&gt;php bin/console doctrine:migration:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pressione &lt;code&gt;yes&lt;/code&gt; para apagar todos os dados do banco de app&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuração
&lt;/h3&gt;

&lt;p&gt;Vamos partir de agora mexer somente nas entidades.&lt;/p&gt;

&lt;p&gt;1.) Importar Attribute ApiResource em sua classe src/Entity/Event.php&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="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Entity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;ApiPlatform\Core\Annotation\ApiResource&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Repository\EventRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Doctrine\ORM\Mapping&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="no"&gt;ORM&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="na"&gt;#[ORM\Entity(repositoryClass: EventRepository::class)]&lt;/span&gt;
&lt;span class="na"&gt;#[ApiResource]&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mf"&gt;...&lt;/span&gt;
        &lt;span class="na"&gt;#[ORM\ManyToOne(targetEntity: Couple::class)]&lt;/span&gt;
    &lt;span class="na"&gt;#[ORM\JoinColumn(name: "couple_id", referencedColumnName: "id", nullable: true)]&lt;/span&gt;
    &lt;span class="na"&gt;#[ApiSubresource]&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$couple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="mf"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.) Importar Attribute ApiResource em sua classe src/Entity/Couple.php&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="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Entity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;ApiPlatform\Core\Annotation\ApiResource&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Repository\CoupleRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Doctrine\Common\Collections\ArrayCollection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Doctrine\Common\Collections\Collection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Doctrine\ORM\Mapping&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="no"&gt;ORM&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="na"&gt;#[ORM\Entity(repositoryClass: CoupleRepository::class)]&lt;/span&gt;
&lt;span class="na"&gt;#[ApiResource]&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Couple&lt;/span&gt;
&lt;span class="mf"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Execute:
&lt;/h3&gt;

&lt;p&gt;Rode seu servidor local php para ter acesso ao localhost&lt;/p&gt;

&lt;p&gt;Acesse: &lt;a href="http://localhost:7777/api" rel="noopener noreferrer"&gt;http://localhost:7777/api&lt;/a&gt; - Swagger documentation RESTAPI&lt;/p&gt;

&lt;p&gt;Acesse: &lt;a href="http://localhost:7777/api" rel="noopener noreferrer"&gt;http://localhost:7777/api/graphql&lt;/a&gt; - Playground GraphQL &lt;/p&gt;

&lt;p&gt;Veja algumas queries que você pode fazer em GraphQL:&lt;/p&gt;

&lt;p&gt;Para criar um novo casal faça isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CretateCouple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$couple&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;createCoupleInput&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="n"&gt;createCouple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$couple&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="n"&gt;couple&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="n"&gt;manName&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;womanName&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="c"&gt;#query variables&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="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;couple&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;manName&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;joe&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;womanName&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;mary&lt;/span&gt;&lt;span class="err"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para buscar todos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&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="n"&gt;couples&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="n"&gt;edges&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="n"&gt;node&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="n"&gt;manName&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;womanName&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Espero que tenham gostado fiz um exemplo bem simples para ajudar a entender mais sobre essas ferramentas tão maravilhosas que nem sempre temos contato.&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://symfony.com/doc/current/setup.html" rel="noopener noreferrer"&gt;Symfony&lt;/a&gt;&lt;br&gt;
&lt;a href="https://api-platform.com/docs/distribution/" rel="noopener noreferrer"&gt;ApiPlatform&lt;/a&gt;&lt;br&gt;
&lt;a href="https://symfony.com/bundles/SymfonyMakerBundle/current/index.html" rel="noopener noreferrer"&gt;Symfony Maker&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>symfony</category>
      <category>laravel</category>
      <category>graphql</category>
    </item>
  </channel>
</rss>
