{"id":2680,"date":"2017-09-10T23:01:59","date_gmt":"2017-09-11T02:01:59","guid":{"rendered":"https:\/\/devkico.itexto.com.br\/?p=2680"},"modified":"2017-09-10T23:01:59","modified_gmt":"2017-09-11T02:01:59","slug":"minha-expedicao-ao-mundo-do-node-js","status":"publish","type":"post","link":"https:\/\/devkico.itexto.com.br\/?p=2680","title":{"rendered":"Minha expedi\u00e7\u00e3o ao mundo do Node.js"},"content":{"rendered":"<p>Este final de semana resolvi mergulhar no Node.js: apesar de ser uma plataforma que acompanho desde o lan\u00e7amento nunca lhe dei a devida aten\u00e7\u00e3o que esta merece, ent\u00e3o resolvi corrigir esta desfeita.<\/p>\n<p>Este mergulho foi uma experi\u00eancia incr\u00edvel, intensa e que me fez refletir sobre diversos assuntos. Aprendi\u00a0<strong>horrores<\/strong> e ent\u00e3o pra finalizar (dar o primeiro grande passo), nada melhor que compartilhar com voc\u00eas minhas conclus\u00f5es iniciais.<\/p>\n<h2>Eu e o Node.js<\/h2>\n<p>Talvez a melhor express\u00e3o para descrever meu relacionamento com Node.js at\u00e9 agora seja\u00a0<em>&#8220;curiosidade distante&#8221;<\/em>. Meu primeiro contato com a plataforma foi quando surgiu: escrevi alguns mocks de webservices e APIs REST l\u00e1 pelos idos de 2009\/2010.<\/p>\n<p>Se n\u00e3o me falha a mem\u00f3ria estes mocks foram escritos usando o m\u00f3dulo <a href=\"https:\/\/nodejs.org\/dist\/latest-v8.x\/docs\/api\/http.html\">HTTP<\/a> mesmo. Na \u00e9poca fiquei muito impressionado pois com <strong>pouqu\u00edssimo\u00a0c\u00f3digo<\/strong> eu conseguia implementar aqueles servidores. Parecia fant\u00e1stico (e era).<\/p>\n<p>Mas na \u00e9poca (e ainda hoje) a JVM dominava minha vida (estou nela desde o Java 1.1 1996\/97). Pra piorar, desde ent\u00e3o vi muitas hist\u00f3rias de terror envolvendo o mau uso: essencialmente a m\u00e1 compreens\u00e3o do modelo ass\u00edncrono, apresenta\u00e7\u00f5es muito ruins sobre o assunto (muito ruins mesmo), hype excessivo, fanboys&#8230; Tudo isto gerou uma p\u00e9ssima impress\u00e3o em mim, o que acabou me distanciando da plataforma.<\/p>\n<p>(eu sei que devia focar minhas impress\u00f5es em aspectos objetivos, mas \u00e9 ineg\u00e1vel (e perigoso) o poder do subjetivo)<\/p>\n<p>De l\u00e1 pra c\u00e1 meu uso do Node.js sempre foi indireto: ou tendo como base ferramentas como o Apache Cordova, Vue.js, at\u00e9 mesmo a escrita de pequenos scripts internos para resolver coisas pequenas do meu dia a dia (usava o comando Node como calculadora). Nada de avan\u00e7ado. Nunca fiz uma aplica\u00e7\u00e3o web real.<\/p>\n<p>Al\u00e9m disto sou da gera\u00e7\u00e3o de programadores que n\u00e3o via o JavaScript com bons olhos. Me surpreende a popularidade da linguagem que, todos sabemos, n\u00e3o foi constru\u00edda sobre a melhor das bases. E esta primeira impress\u00e3o ainda exerce influencia sobre mim. Curiosamente mesmo assim JavaScript sempre foi uma das linguagens que mais dominei. Um sentimento do tipo: <em>&#8220;sei que voc\u00ea tem muitos problemas, mas os ignoro e gosto de voc\u1ebd&#8221;<\/em>.<\/p>\n<h2>Come\u00e7a a expedi\u00e7\u00e3o ao redor do meu quarto<\/h2>\n<figure id=\"attachment_2682\" aria-describedby=\"caption-attachment-2682\" style=\"width: 200px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/pt.wikipedia.org\/wiki\/Voyage_autour_de_ma_chambre\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2682 size-full\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/viagem_redor_do_meu_quarto.jpg\" alt=\"\" width=\"200\" height=\"382\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/viagem_redor_do_meu_quarto.jpg 200w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/viagem_redor_do_meu_quarto-157x300.jpg 157w\" sizes=\"(max-width: 200px) 100vw, 200px\" \/><\/a><figcaption id=\"caption-attachment-2682\" class=\"wp-caption-text\">Um bom livro: recomendo!<\/figcaption><\/figure>\n<p>Navegando pelo Udemy topei com uma promo\u00e7\u00e3o envolvendo este curso:\u00a0<a href=\"https:\/\/www.udemy.com\/the-complete-nodejs-developer-course-2\/\"><em>The Complete Node.js Developer Course (2nd Edition)<\/em><\/a>. Custava R$ 20,00, os livros em portugu\u00eas que havia lido a respeito detestei (idem os cursos), vi a ementa, li muitos reviews positivos, tinha um fim de semana livre, o neg\u00f3cio era barato e me bateu aquela vontade de aprender Node.js. Comprei. (a prop\u00f3sito, o curso \u00e9 maravilhoso, recomendo)<\/p>\n<p>De onde bateu esta vontade de aprender Node.js? Honesta e pura curiosidade e vontade de tirar a m\u00e1 impress\u00e3o que tinha da coisa. E dado que j\u00e1 estou h\u00e1 mais da metade da minha vida na JVM, que se tornou uma esp\u00e9cie de &#8220;ilha de Lost&#8221; pra mim, por que n\u00e3o tentar sair um pouquinho deste mundo e minimizar meu <a href=\"https:\/\/devkico.itexto.com.br\/?p=172\">determinismo lingu\u00edstico<\/a>? De quebra eu ainda aprenderia um pouco mais sobre o ES6 e algumas ferramentas novas. Come\u00e7ava a expedi\u00e7\u00e3o.<\/p>\n<p>(spoiler: ainda considero a JVM como a melhor plataforma de todos os tempos)<\/p>\n<figure id=\"attachment_2684\" aria-describedby=\"caption-attachment-2684\" style=\"width: 411px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.devall.com.br\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2684 \" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/banner_facebook.png\" alt=\"\" width=\"411\" height=\"215\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/banner_facebook.png 1200w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/banner_facebook-300x157.png 300w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/banner_facebook-768x402.png 768w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/banner_facebook-1024x536.png 1024w\" sizes=\"(max-width: 411px) 100vw, 411px\" \/><\/a><figcaption id=\"caption-attachment-2684\" class=\"wp-caption-text\">J\u00e1 acessou hoje? Devia!<\/figcaption><\/figure>\n<p>Mas este meu mergulho deveria ter um objetivo final: eu saberia se Node.js valeria \u00e0 pena se constru\u00edsse uma prova de conceito que o validasse enquanto tecnologia. Qual prova de conceito? Simples: <strong>reescrever parcialmente o<a href=\"http:\/\/devall.com.br\"> \/dev\/All<\/a> em Node.js<\/strong> e descobrir se o neg\u00f3cio escala mesmo, assim como se o ferramental me fornece produtividade similar \u00e0 que tenho com Grails.<\/p>\n<p>(o resultado foi muito interessante, aguarde e ver\u00e1)<\/p>\n<h2>\/dev\/All &#8211; Node.js ou Grails?<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-604\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2010\/02\/grails_logo.png\" alt=\"\" width=\"163\" height=\"43\" \/><\/p>\n<p>O \/dev\/All tem dois componentes: o &#8220;Feed Hunter&#8221;, que \u00e9 o respons\u00e1vel por obter os links que aparecem no site (escrito em Java usando Spring, Apache Camel e outras cositas sobre as quais escreverei em breve por que v\u00eam surpresa a\u00ed) e o &#8220;Front-end&#8221;, feito inteiramente em Grails (3.1.9) e Vue.js.<\/p>\n<p>Um dos nossos objetivos na evolu\u00e7\u00e3o do Front-end \u00e9 transform\u00e1-lo em um <a href=\"https:\/\/en.wikipedia.org\/wiki\/Single-page_application\">SPA<\/a>, desacoplando-o completamente do c\u00f3digo Grails (sim, eventualmente haver\u00e1 um app, no qual j\u00e1 estou trabalhando). J\u00e1 demos alguns passos nesta separa\u00e7\u00e3o, o que se manifesta na ado\u00e7\u00e3o do Vue.js: o c\u00f3digo Grails seria ent\u00e3o apenas uma API REST dali pra frente.<\/p>\n<p>Apesar de todos os nossos esfor\u00e7os, ainda acho este componente pesado: ocupa no m\u00ednimo algo em torno de 300 a 400 Mb de RAM no servidor. A vida inteira escuto que Java devora mem\u00f3ria. Sendo assim decidi que minha prova de conceito seria a implementa\u00e7\u00e3o de uma API que j\u00e1 existe no \/dev\/All: aquela respons\u00e1vel por obter os posts apresentados na p\u00e1gina inicial. Este endpoint <a href=\"http:\/\/devall.com.br\/api\/posts\">aqui<\/a>.<\/p>\n<h3>Um pouco mais sobre o modelo de desenvolvimento atual e o da prova de conceito<\/h3>\n<p>O modelo de desenvolvimento atual usa como base aquilo que o Grails nos prov\u00ea por padr\u00e3o: usamos o GORM como ORM e a pr\u00f3pria estrutura de controladores do framework para implementar estas APIs. \u00c9 not\u00f3rio portanto que h\u00e1 aqui um custo adicional de mem\u00f3ria\/desempenho relativo ao ORM, entretanto no que diz respeito \u00e0 produtividade, comparando o custo do desenvolvedor e do servidor, produtividade ganha e portanto o ORM fica.<\/p>\n<p>O SGBD adotado \u00e9 o MySQL: e a\u00ed entra a primeira dificuldade em rela\u00e7\u00e3o ao material existente sobre o Node.js: 99% do que existe hoje usa o MongoDB como base de dados. Eu teria de aprender portanto como usar o MySQL com Node.js. Usei o m\u00f3dulo <a href=\"https:\/\/www.npmjs.com\/package\/mysql\">mysql<\/a> na vers\u00e3o 2.5.4 (e o aprendizado foi super r\u00e1pido).<\/p>\n<p>No caso do Node.js n\u00e3o encontrei um m\u00f3dulo de ORM com bases relacionais e, sinceramente, desta vez quis evitar. Um dos meus objetivos foi tamb\u00e9m fugir um pouco do desenvolvimento estritamente orientado a objetos e partir para uma abordagem mais funcional (quem acompanha este blog sabe que tenho l\u00e1 <a href=\"https:\/\/devkico.itexto.com.br\/?p=1324\">meus problemas com OO<\/a>).<\/p>\n<h2>As impress\u00f5es<\/h2>\n<h3>JavaScript \u00a0&#8211; ES6<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2637\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/08\/logotipo.png\" alt=\"\" width=\"256\" height=\"256\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/08\/logotipo.png 256w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/08\/logotipo-150x150.png 150w\" sizes=\"(max-width: 256px) 100vw, 256px\" \/><\/p>\n<p>Foi uma excelente oportunidade para aprender de vez o ES6 e aqui aquela minha antiga impress\u00e3o a respeito da linguagem foi embora. Querendo ou n\u00e3o eu acabava escrevendo c\u00f3digo JavaScript tal como havia o conhecido l\u00e1 no in\u00edcio da minha carreira no final dos anos 90: de repente veio um upgrade gigantesco e muitas das coisas que n\u00e3o conseguia entender se tornaram claras.<\/p>\n<p>J\u00e1 faz algum tempo que estava me dedicando ao estudo da linguagem, mas ainda n\u00e3o havia me debru\u00e7ado sobre o ES6. Foi sem sombra de d\u00favidas uma verdadeira reciclagem neste aspecto. Muitas coisas que n\u00e3o entendia agora fazem sentido:fun\u00e7\u00f5es arrow, a modularidade, e muitos aspectos envolvendo melhorias da pr\u00f3pria sintaxe.<\/p>\n<h3>Ferramental do Node.js e tempo de execu\u00e7\u00e3o<\/h3>\n<p>Uma surpresa maravilhosa: tal como no Grails, tudo o que preciso para trabalhar \u00e9 da interface de linha de comando e um editor de textos. Mas mais do que isto, as ferramentas em si s\u00e3o bastante produtivas: nodemon para carregamento autom\u00e1tico das mudan\u00e7as que realizo no c\u00f3digo fonte, \u00a0as ferramentas de depura\u00e7\u00e3o nativas do Node, o pr\u00f3prio npm (que j\u00e1 conhecia e inclusive devemos lan\u00e7ar um guia esta semana)&#8230; Fant\u00e1stico pra dizer o m\u00ednimo.<\/p>\n<p>O carregamento do c\u00f3digo e o tempo de execu\u00e7\u00e3o foram surpreendentes:\u00a0<strong>muito<\/strong> mais r\u00e1pido que o que eu esperava. Sobre isto vou inclusive falar mais \u00e0 frente.<\/p>\n<h3>Escrita de testes com Mocha, Expect e Supertest<\/h3>\n<p>Sempre que vou aprender algo novo os testes viram meu laborat\u00f3rio. At\u00e9 ent\u00e3o escrevia meus testes no navegador usando o <a href=\"https:\/\/jasmine.github.io\/\">Jasmine<\/a>. \u00c9 uma solu\u00e7\u00e3o legal, mas nesta expedi\u00e7\u00e3o acabei conhecendo o Mocha, que \u00e9 inclusive muito parecido. N\u00e3o houve grandes mudan\u00e7as para mim neste ponto portanto.<\/p>\n<p>O interessante veio com o <a href=\"https:\/\/github.com\/mjackson\/expect\">Expect<\/a>: ele tem uma funcionalidade muito interessante chamada &#8220;spy&#8221;. Essencialmente \u00e9 um &#8220;AOP para testes&#8221;, que te permite verificar se um m\u00e9todo foi ou n\u00e3o chamado.<\/p>\n<p>O <a href=\"https:\/\/www.npmjs.com\/package\/supertest\">Supertest<\/a> tamb\u00e9m achei muito bacana: \u00e9 usado para escrever testes em cima de requisi\u00e7\u00f5es HTTP geradas pelo Express, ou seja, me permite escrever os testes funcionais de uma forma bastante simples.<\/p>\n<p>O bacana \u00e9 que com o nodemon podemos ter os testes executando a cada altera\u00e7\u00e3o que fazemos no c\u00f3digo, isto se mostrou uma m\u00e3o na roda no meu laborat\u00f3rio interno.<\/p>\n<h3>O <a href=\"http:\/\/expressjs.com\">ExpressJS<\/a><\/h3>\n<p>Do lado JVM j\u00e1 temos alternativas que seguem a dire\u00e7\u00e3o do ExpressJS, como o <a href=\"http:\/\/ratpack.io\">Ratpack<\/a> (n\u00e3o conhece? devia!) e o <a href=\"http:\/\/vertx.io\">Vert.x<\/a> (literalmente o Node na JVM). \u00c9 o modelo de desenvolvimento que considero ideal quando estamos escrevendo APIs: f\u00e1cil, direto, focado no que vamos fazer (a implementa\u00e7\u00e3o dos endpoints).<\/p>\n<p>Confesso que apenas\u00a0<strong>amei<\/strong> o ExpressJS. A documenta\u00e7\u00e3o n\u00e3o \u00e9 t\u00e3o boa quanto a do Grails, mas te fornece o essencial para que voc\u00ea possa fazer praticamente tudo com ele, e de uma forma muito simples.<\/p>\n<p>Nem tudo \u00e9 claro: o uso de sess\u00f5es, por exemplo, n\u00e3o \u00e9 t\u00e3o \u00f3bvio (mais a frente conto o por qu\u00ea das sess\u00f5es), idem no que diz respeito \u00e0 implementa\u00e7\u00e3o de coisas como o CORS. Entretanto, quando voc\u00ea conhece o conceito de middlewares (o equivalente aos filtros da API Servlet) a coisa deslancha.<\/p>\n<p>Sobre os templates, sim: h\u00e1 a renderiza\u00e7\u00e3o de p\u00e1ginas tal como o JSP do Java EE ou o GSP do Grails. Para tal experimentei o <a href=\"https:\/\/www.npmjs.com\/package\/mustache\">Mustache<\/a>, <a href=\"https:\/\/pugjs.org\/api\/getting-started.html\">Pug<\/a> e <a href=\"https:\/\/www.npmjs.com\/package\/ejs\">EJS<\/a>. Comparado ao que temos do lado Java s\u00e3o solu\u00e7\u00f5es muito primitivas: o GSP sem sombra de d\u00favidas est\u00e1 anos luz na frente. Mas \u00e9 natural isto: a pegada do Node.js sempre foi muito mais no desenvolvimento de aplica\u00e7\u00f5es que seguem o padr\u00e3o SPA, o que joga este tipo de solu\u00e7\u00e3o para o segundo plano. Acabei optando pelo <a href=\"https:\/\/www.npmjs.com\/package\/hbs\">hbs<\/a> (Handlebars) na minha prova de conceito.<\/p>\n<p>No frigir dos ovos \u00e9 um framework extremamente produtivo. No meu caso, que s\u00f3 conhecia (e muito pouco) o m\u00f3dulo http, foi uma bela surpresa.<\/p>\n<h3>O poder e a ilus\u00e3o de poder<\/h3>\n<p>Quase tudo que vi no Node achei muito produtivo: e \u00e9 mesmo, mas apenas se voc\u00ea sabe o que est\u00e1 fazendo. Parece \u00f3bvio, n\u00e9? Mas n\u00e3o \u00e9: JavaScript ainda \u00e9 aquela linguagem que a maior parte das pessoas diz conhecer mas nunca estudou a respeito.<\/p>\n<p>Lembra as hist\u00f3rias de terror que mencionei no in\u00edcio deste post? Pelo que pude ver sempre surgiram das mesmas causas:<\/p>\n<ul>\n<li>Falta de conhecimento acerca do modelo de desenvolvimento ass\u00edncrono que o Node adota (o n\u00e3o conhecimento do loop de eventos \u00e9 fatal).<\/li>\n<li>Tem de conhecer o paradigma funcional.<\/li>\n<li>A falta de conhecimento sobre desenvolvimento backend &#8211; Node foi feito para ser executado no servidor. Vi muita gente sem conhecimento algum desta \u00e1rea, mas muito de JavaScript cometendo erros absurdos aqui.<\/li>\n<li>Desconhecimento das nuances do JavaScript (coisas como == e ===, por exemplo, o pr\u00f3prio escopo de vari\u00e1veis, etc)<\/li>\n<\/ul>\n<p>A ferramenta \u00e9 realmente muito poderosa, \u00e9 \u00a0muito f\u00e1cil de usar e voc\u00ea de fato tem as coisas rodando num tempo muito menor. Mas quando ignora estes pontos acima a coisa fica feia, muito feia.<\/p>\n<p>A armadilha surge no fato do Node ter uma \u00fanica thread (\u00e9 poss\u00edvel ter um servidor com mais de um processo, basta usar o m\u00f3dulo <a href=\"https:\/\/nodejs.org\/api\/cluster.html\">cluster<\/a>, mas n\u00e3o \u00e9 o padr\u00e3o). Qualquer opera\u00e7\u00e3o de I\/O que agarre, prende todas as requisi\u00e7\u00f5es que chegam no seu servidor: sendo assim voc\u00ea n\u00e3o &#8220;tem de pensar assincronamente&#8221;, voc\u00ea \u00e9\u00a0<strong>obrigado<\/strong>.<\/p>\n<p>Mais do que pensar assincronamente, voc\u00ea precisa pensar\u00a0<strong>funcionalmente<\/strong>. Se o desenvolvedor n\u00e3o tiver bem fixados os conceitos do paradigma funcional \u00e9 quase certo que vai dar merda. E quer saber de uma coisa? Acho isto fant\u00e1stico, por que sair um pouco do OO foi uma experi\u00eancia quase terap\u00eautica para mim (j\u00e1 mencionei que <a href=\"https:\/\/devkico.itexto.com.br\/?p=1324\">n\u00e3o curto tanto OO<\/a>?).<\/p>\n<p>Se n\u00e3o souber estas coisas, voc\u00ea n\u00e3o tem poder: tem a ilus\u00e3o de poder e a garantia de estar criando mais hist\u00f3rias tristes que se propagar\u00e3o por a\u00ed.\u00a0Rapadura \u00e9 doce, mas n\u00e3o \u00e9 mole n\u00e3o.<\/p>\n<h2>E a sua prova de conceito, como ficou?<\/h2>\n<p>Bom, vamos aos resultados ent\u00e3o. Comecei pela implementa\u00e7\u00e3o de um \u00fanico endpoint: o respons\u00e1vel por realizar a busca por posts no \/dev\/All (este <a href=\"http:\/\/devall.com.br\/api\/posts\">aqui<\/a>). Foi algo f\u00e1cil de fazer: este endpoint me retorna a lista de posts, e cada elemento no post tem uma estrutura similar \u00e0 seguinte:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n{\r\n id:&quot;id do post&quot;,\r\n titulo:&quot;titulo do post&quot;,\r\n resumo:&quot;o resumo do post&quot;,\r\n dataPublicacao:&quot;a data em que o post foi publicado no post&quot;,\r\n dataInclusao:&quot;a data em que o \/dev\/All encontrou o post e o incluiu no banco de dados&quot;,\r\n cliques:&quot;quantos cliques recebeu o post&quot;,\r\n site:{\r\n  id:&quot;identificador do blog que cont\u00e9m o post&quot;,\r\n  nome:&quot;o nome do blog&quot;,\r\n  url:&quot;a URL do blog&quot;,\r\n  autor:{\r\n  id:&quot;o identificador do autor do blog&quot;,\r\n  nome:&quot;O nome do autor do blog&quot;\r\n }\r\n }\r\n}\r\n\r\n<\/pre>\n<p>H\u00e1 portanto tr\u00eas tabelas no banco de dados unidas por join: post, site e autor. Lembre: n\u00e3o estou usando MongoDB aqui, mas sim o MySQL. Ser\u00e1 que a coisa escala? Comecei a realizar ent\u00e3o alguns testes de desempenho e o resultado foi &#8220;apenas&#8221; assustador como mostrarei na sequ\u00eancia.<\/p>\n<p>A chamada padr\u00e3o a este endpoint retorna os \u00faltimos 20 posts cadastrados no \/dev\/All. Em m\u00e9dia o tamanho da resposta \u00e9 20kb.<\/p>\n<h3>Teste de desempenho e escalabilidade<\/h3>\n<p>Para realizar o teste usei uma ferramenta chamada &#8220;<a href=\"https:\/\/www.joedog.org\/siege-home\/\">siege<\/a>&#8220;, que me permite realizar testes de carga usando o protocolo HTTP. Caso esteja usando Linux, voc\u00ea pode instal\u00e1-la usando o comando <code>apt-get install siege<\/code>.<\/p>\n<p>Inicialmente peguei a mesma implementa\u00e7\u00e3o feita em Grails e a instalei em um servidor Tomcat local (exatamente como se encontra em produ\u00e7\u00e3o). Na sequ\u00eancia, executei os testes usando o Siege levando em considera\u00e7\u00e3o o tempo de um minuto e 255 usu\u00e1rios simult\u00e2neos. Vamos aos valores aproximados para a <strong>vers\u00e3o escrita em Grails<\/strong>:<br \/>\nTransactions: \u00a0 \u00a0 \u00a0 21046 hits<br \/>\nAvailability: \u00a0 \u00a0 \u00a0100.00 %<br \/>\nElapsed time: \u00a0 \u00a0 \u00a0 59.95 secs<br \/>\nData transferred: \u00a0 \u00a0 \u00a0245.47 MB<br \/>\nResponse time: \u00a0 \u00a0 \u00a0 \u00a00.47 secs<br \/>\n<strong>Transaction rate: \u00a0 \u00a0 \u00a0351.06 trans\/sec<\/strong><\/p>\n<p>Agora, vamos aos resultados na mesma API, implementada em Node.js usando as mesmas configura\u00e7\u00f5es:<br \/>\nTransactions: \u00a0 \u00a0 \u00a0 32596 hits<br \/>\nAvailability: \u00a0 \u00a0 \u00a0100.00 %<br \/>\nElapsed time: \u00a0 \u00a0 \u00a0 59.06 secs<br \/>\nData transferred: \u00a0 \u00a0 \u00a0131.28 MB<br \/>\nResponse time: \u00a0 \u00a0 \u00a0 \u00a00.21 secs<br \/>\n<strong>Transaction rate: \u00a0 \u00a0 \u00a0551.91 trans\/sec<\/strong><\/p>\n<p>Na m\u00e9dia a mesma API escrita em Node.js consegue um throughput maior: <strong>40 a 50% a mais de transa\u00e7\u00f5es por segundo<\/strong>.<\/p>\n<p>E sobre o consumo de mem\u00f3ria? Na m\u00e9dia enquanto o Tomcat consome 1 Gb durante o teste, a inst\u00e2ncia do Node consome 170Mb. <strong>80% a menos<\/strong>.<\/p>\n<h4>Mas este benchmark n\u00e3o \u00e9 preciso, ent\u00e3o n\u00e3o comemore ainda<\/h4>\n<p>N\u00e3o comemore ainda: pra come\u00e7ar este \u00e9 um benchmark muito vagabundo. Voc\u00ea deve levar em considera\u00e7\u00e3o os seguintes pontos:<\/p>\n<ul>\n<li>O c\u00f3digo escrito em Grails usa o GORM e cont\u00e9m uma s\u00e9rie de funcionalidades carregadas junto com a aplica\u00e7\u00e3o que n\u00e3o existem ainda no c\u00f3digo escrito em Node.js.<\/li>\n<li>O c\u00f3digo escrito em Node.js usa apenas SQL nativo para obter os dados, o que d\u00e1 um ganho de desempenho em rela\u00e7\u00e3o \u00e0 ado\u00e7\u00e3o de qualquer ORM.<\/li>\n<\/ul>\n<p>N\u00e3o cheguei a implementar uma vers\u00e3o usando apenas SQL do mesmo endpoint na aplica\u00e7\u00e3o, entretanto creio que o resultado seria muito parecido mesmo assim, pois ainda h\u00e1 uma enorme pilha por tr\u00e1s. Al\u00e9m disto, \u00e9 fato conhecido que sim, Java sempre consome uma quantidade significativamente maior de mem\u00f3ria.<\/p>\n<p>Os testes foram al\u00e9m: depois executei verifica\u00e7\u00f5es com 500, 1000 usu\u00e1rios simult\u00e2neos. A disponibilidade e escalabilidade do Node.js ganhou nestes casos (note: estou testando apenas um endpoint).<\/p>\n<p>Resumindo: obtive resultados melhores do ponto de vista\u00a0<strong>emp\u00edrico<\/strong> com Node: mas minha metodologia de teste \u00e9 muito furada e n\u00e3o deve ser levada como palavra final.<\/p>\n<h3>E depois de ter implementado a API?<\/h3>\n<p>Bom: a\u00ed eu empolguei e implementei quase todo o comonente Frontend do \/dev\/All em Node.js. H\u00e1 uma vers\u00e3o <strong>muito tosca<\/strong> online caso queira conferir: ela tem apenas a p\u00e1gina inicial, mas d\u00e1 pra pelo menos voc\u00ea experimentar. Basta acessar <a href=\"http:\/\/devall.com.br:3000\">http:\/\/devall.com.br:3000<\/a> (n\u00e3o sei at\u00e9 quando este link estar\u00e1 dispon\u00edvel, pois \u00e9 apenas para testes).<\/p>\n<p>Escrevi a p\u00e1gina inicial usando o hbs, ou seja, n\u00e3o \u00e9 uma aplica\u00e7\u00e3o SPA: meu objetivo era apenas aprender e testar a tecnologia, sendo assim leve isto em considera\u00e7\u00e3o quando a estiver accessando, ok?<\/p>\n<h2>Minhas considera\u00e7\u00f5es finais<\/h2>\n<p>Node.js com certeza faz parte agora do meu cinto de utilidades, e saibam que em pouqu\u00edssimo tempo teremos um novo front-end do \/dev\/All 100% implementado nesta tecnologia pelas seguintes raz\u00f5es:<\/p>\n<ul>\n<li>Nosso front-end \u00e9 muito pequeno, ent\u00e3o \u00e9 vi\u00e1vel de ser reescrito (todo o trabalho pesado \u00e9 feito pelo\u00a0<em>Feed Hunter<\/em>).<\/li>\n<li>O consumo de mem\u00f3ria \u00e9 realmente\u00a0<strong>muito menor<\/strong>, o que nos permite aproveitar melhor nossos servidores e reduzir o custo de opera\u00e7\u00e3o.<\/li>\n<li>A escalabilidade se mostrou bastante superior.<\/li>\n<li>E nesta minha empolga\u00e7\u00e3o j\u00e1 estou com 80% disto implementado e, no processo, sem os v\u00edcios das vers\u00f5es anteriores do c\u00f3digo fonte. :)<\/li>\n<\/ul>\n<p>\u00c9 vital no entanto lembrar do que escrevi acima a respeito da ilus\u00e3o de poder. <strong>\u00c9 assustadoramente f\u00e1cil escrever c\u00f3digo lento e que n\u00e3o escalar\u00e1 em Node.js<\/strong>. Ficou \u00f3bvio pra mim a origem das hist\u00f3rias tristes que havia mencionado antes. Se voc\u00ea n\u00e3o souber programa\u00e7\u00e3o funcional, entender o modelo ass\u00edncrono e de eventos do Node.js, \u00e9 quase certo que vai dar errado.<\/p>\n<p>(\u00e9 importante lembrar que JavaScript ainda \u00e9 aquela linguagem que a maioria julga saber mas nunca estudou de verdade, e isto \u00e9 a origem de in\u00fameros problemas)<\/p>\n<h3>Sobre a produtividade em rela\u00e7\u00e3o ao Grails<\/h3>\n<p>Do ponto de vista de produtividade, comparado ao Grails, sinceramente n\u00e3o posso dizer que seja mais produtivo que este. Os plug-ins do Grails, al\u00e9m do pr\u00f3prio GSP o tornam matador quando h\u00e1 renderiza\u00e7\u00e3o do lado servidor. Isto sem mencionar que a linguagem Groovy tamb\u00e9m \u00e9 melhor que JavaScript (ao menos \u00e9 constru\u00edda sobre bases bem mais s\u00f3lidas).<\/p>\n<p>Ainda sobre produtividade comparado ao Grails: aqui n\u00f3s pensamos de forma s\u00edncrona, que \u00e9 muito mais natural para a esmagadora maioria das pessoas. No Node.js pensamos essencialmente em callbacks e promises e c\u00f3digo que escrevemos para ser executado no futuro, e n\u00e3o no agora. E sim: se adequar a esta outra realidade leva tempo e, portanto, boa parte da sua produtividade tamb\u00e9m.<\/p>\n<p>Entretanto no que diz respeito ao carregamento do c\u00f3digo fonte e sua modifica\u00e7\u00e3o durante a execu\u00e7\u00e3o, Node.js chuta a bunda do Grails diversas vezes. \u00c9 muito mais r\u00e1pido, e isto \u00e9 fundamental quando vamos executar uma grande bateria de testes.<\/p>\n<h3>Sobre modularidade e grandes bases de c\u00f3digo<\/h3>\n<p>A quest\u00e3o da modularidade tamb\u00e9m \u00e9 importante mencionar: j\u00e1 trabalhei em projetos gigantescos com Grails (e Java em geral). No caso do Node.js, ainda n\u00e3o peguei um projeto com uma grande base de c\u00f3digo. Entretanto, para escrever micro-servi\u00e7os, Node.js se mostrou uma ferramenta\u00a0<strong>extremamente interessante<\/strong> e com certeza est\u00e1 no centro do meu radar para estes casos.<\/p>\n<h3>Sobre o consumo de recursos e escalabilidade<\/h3>\n<p>N\u00e3o h\u00e1 muito o que dizer: consome uma quantidade muito menor de mem\u00f3ria e quando bem projetado escala maravilhosamente bem. \u00c9 portanto um forte candidato em situa\u00e7\u00f5es nas quais temos servidores limitados (que \u00e9 justamente uma \u00e1rea na qual venho pesquisando bastante nos \u00faltimos anos).<\/p>\n<p>O consumo da CPU tamb\u00e9m se mostrou muito inferior. No caso dos testes que realizei, c\u00f3digo na JVM chegava a consumir 350% da CPU f\u00e1cil, enquanto o Node ficava na faixa dos 120%.<\/p>\n<p>Resumindo: se voc\u00ea souber o que est\u00e1 fazendo o resultado \u00e9 lindo.<\/p>\n<h3>Renderiza\u00e7\u00e3o do lado servidor<\/h3>\n<p>N\u00e3o \u00e9 algo lindo: tal como mencionei as op\u00e7\u00f5es que encontrei ainda s\u00e3o muito primitivas quando comparadas ao que temos em Java, Groovy ou PHP. Natural, n\u00e3o \u00e9 o foco deste p\u00fablico. Para aplica\u00e7\u00f5es que requeiram a cria\u00e7\u00e3o de v\u00e1rios CRUDs algo como Grails ainda \u00e9 uma solu\u00e7\u00e3o bem mais interessante.<\/p>\n<p>Mas aqui leve em considera\u00e7\u00e3o minha pouca experi\u00eancia no assunto. Pode ser que existam solu\u00e7\u00f5es que eu ainda n\u00e3o conhe\u00e7a.<\/p>\n<h3>E finalmente<\/h3>\n<p>Este foi um final de semana maravilhoso e estas foram as minhas conclus\u00f5es iniciais sobre aquilo que estudei (por isto o post longo).<\/p>\n<p>Neste primeiro momento recomendo o Node para pequenos projetos, especialmente se for projetos nos quais voc\u00ea implementar\u00e1 apenas uma API. \u00c9 uma tecnologia muito bacana e que vale \u00e0 pena estudar.<\/p>\n<p>Conforme progrido no estudo conto mais pra voc\u00eas aqui.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ap\u00f3s um mergulho no Node.js, quais as minhas conclus\u00f5es iniciais sobre a plataforma em rela\u00e7\u00e3o ao JavaEE (especialmente Grails) e o futuro do front-end do \/dev\/All.<br \/>\nMe acompanhe nesta expedi\u00e7\u00e3o ao redor do meu quarto que foi realizada neste final de semana!<\/p>\n","protected":false},"author":1,"featured_media":2681,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[72,78],"tags":[],"class_list":["post-2680","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript-2","category-node-js"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Minha expedi\u00e7\u00e3o ao mundo do Node.js - \/dev\/Kico<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/devkico.itexto.com.br\/?p=2680\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Minha expedi\u00e7\u00e3o ao mundo do Node.js - \/dev\/Kico\" \/>\n<meta property=\"og:description\" content=\"Ap\u00f3s um mergulho no Node.js, quais as minhas conclus\u00f5es iniciais sobre a plataforma em rela\u00e7\u00e3o ao JavaEE (especialmente Grails) e o futuro do front-end do \/dev\/All. Me acompanhe nesta expedi\u00e7\u00e3o ao redor do meu quarto que foi realizada neste final de semana!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/devkico.itexto.com.br\/?p=2680\" \/>\n<meta property=\"og:site_name\" content=\"\/dev\/Kico\" \/>\n<meta property=\"article:published_time\" content=\"2017-09-11T02:01:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"424\" \/>\n\t<meta property=\"og:image:height\" content=\"274\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@loboweissmann\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=2680\",\"url\":\"https:\/\/devkico.itexto.com.br\/?p=2680\",\"name\":\"Minha expedi\u00e7\u00e3o ao mundo do Node.js - \/dev\/Kico\",\"isPartOf\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=2680#primaryimage\"},\"image\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=2680#primaryimage\"},\"thumbnailUrl\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png\",\"datePublished\":\"2017-09-11T02:01:59+00:00\",\"dateModified\":\"2017-09-11T02:01:59+00:00\",\"author\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\"},\"breadcrumb\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=2680#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/devkico.itexto.com.br\/?p=2680\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=2680#primaryimage\",\"url\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png\",\"contentUrl\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png\",\"width\":424,\"height\":274},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=2680#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/devkico.itexto.com.br\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Minha expedi\u00e7\u00e3o ao mundo do Node.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\",\"url\":\"https:\/\/devkico.itexto.com.br\/\",\"name\":\"\/dev\/Kico\",\"description\":\"Desenvolvendo software\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/devkico.itexto.com.br\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\",\"name\":\"Kico (Henrique Lobo Weissmann)\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"caption\":\"Kico (Henrique Lobo Weissmann)\"},\"sameAs\":[\"https:\/\/x.com\/loboweissmann\"],\"url\":\"https:\/\/devkico.itexto.com.br\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Minha expedi\u00e7\u00e3o ao mundo do Node.js - \/dev\/Kico","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/devkico.itexto.com.br\/?p=2680","og_locale":"pt_BR","og_type":"article","og_title":"Minha expedi\u00e7\u00e3o ao mundo do Node.js - \/dev\/Kico","og_description":"Ap\u00f3s um mergulho no Node.js, quais as minhas conclus\u00f5es iniciais sobre a plataforma em rela\u00e7\u00e3o ao JavaEE (especialmente Grails) e o futuro do front-end do \/dev\/All. Me acompanhe nesta expedi\u00e7\u00e3o ao redor do meu quarto que foi realizada neste final de semana!","og_url":"https:\/\/devkico.itexto.com.br\/?p=2680","og_site_name":"\/dev\/Kico","article_published_time":"2017-09-11T02:01:59+00:00","og_image":[{"width":424,"height":274,"url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png","type":"image\/png"}],"author":"Kico (Henrique Lobo Weissmann)","twitter_card":"summary_large_image","twitter_creator":"@loboweissmann","twitter_misc":{"Escrito por":"Kico (Henrique Lobo Weissmann)","Est. tempo de leitura":"18 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/devkico.itexto.com.br\/?p=2680","url":"https:\/\/devkico.itexto.com.br\/?p=2680","name":"Minha expedi\u00e7\u00e3o ao mundo do Node.js - \/dev\/Kico","isPartOf":{"@id":"https:\/\/devkico.itexto.com.br\/#website"},"primaryImageOfPage":{"@id":"https:\/\/devkico.itexto.com.br\/?p=2680#primaryimage"},"image":{"@id":"https:\/\/devkico.itexto.com.br\/?p=2680#primaryimage"},"thumbnailUrl":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png","datePublished":"2017-09-11T02:01:59+00:00","dateModified":"2017-09-11T02:01:59+00:00","author":{"@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7"},"breadcrumb":{"@id":"https:\/\/devkico.itexto.com.br\/?p=2680#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/devkico.itexto.com.br\/?p=2680"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/devkico.itexto.com.br\/?p=2680#primaryimage","url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png","contentUrl":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png","width":424,"height":274},{"@type":"BreadcrumbList","@id":"https:\/\/devkico.itexto.com.br\/?p=2680#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/devkico.itexto.com.br\/"},{"@type":"ListItem","position":2,"name":"Minha expedi\u00e7\u00e3o ao mundo do Node.js"}]},{"@type":"WebSite","@id":"https:\/\/devkico.itexto.com.br\/#website","url":"https:\/\/devkico.itexto.com.br\/","name":"\/dev\/Kico","description":"Desenvolvendo software","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/devkico.itexto.com.br\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"pt-BR"},{"@type":"Person","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7","name":"Kico (Henrique Lobo Weissmann)","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","caption":"Kico (Henrique Lobo Weissmann)"},"sameAs":["https:\/\/x.com\/loboweissmann"],"url":"https:\/\/devkico.itexto.com.br\/?author=1"}]}},"jetpack_featured_media_url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2017\/09\/nodejs-logo.png","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2680"}],"collection":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2680"}],"version-history":[{"count":8,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2680\/revisions"}],"predecessor-version":[{"id":2691,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2680\/revisions\/2691"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/media\/2681"}],"wp:attachment":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2680"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}