{"id":1640,"date":"2026-09-22T22:42:45","date_gmt":"2026-09-23T01:42:45","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/?p=1640"},"modified":"2026-09-22T22:53:21","modified_gmt":"2026-09-23T01:53:21","slug":"vue-go-echo-v5-parte-1-ambiente-e-primeira-api","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/vue-go-echo-v5-parte-1-ambiente-e-primeira-api\/","title":{"rendered":"Vue.js + Go with Echo v5, part 1: environment and first API"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/09\/vue-go-echo-v5-parte-1.webp\" alt=\"Mascote LinuxPro programando numa esta\u00e7\u00e3o com o logo do Vue na tela e o gopher do Go na mesa, com o cachorro caramelo cyborg deitado ao lado\" width=\"1486\" height=\"856\" \/><\/p>\n<p><strong>S\u00e9rie Vue.js + Go com Echo v5:<\/strong> <a href=\"\/2026\/09\/vue-go-echo-v5-parte-1-ambiente-e-primeira-api\/\">Parte 1: ambiente e primeira API<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-2-frontend-vue-com-vite\/\">Parte 2: frontend Vue com Vite<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-3-api-rest-de-tarefas\/\">Parte 3: API REST de tarefas<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-4-login-com-sessao-e-cookie\/\">Parte 4: login com sess\u00e3o e cookie<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-5-embed-binario-unico-e-docker\/\">Parte 5: embed, bin\u00e1rio \u00fanico e Docker<\/a><\/p>\n<p><strong>C\u00f3digo completo:<\/strong> todos os arquivos da s\u00e9rie est\u00e3o no <a href=\"https:\/\/gist.github.com\/jniltinho\/c95a0e7bbad4afe779cf143674cbef08\">gist vue-go-echo-v5<\/a>, com um README que mostra em qual pasta cada um fica.<\/p>\n<p>Um frontend em Vue.js e um backend em Go formam uma dupla muito pr\u00e1tica para ferramentas internas, pain\u00e9is e pequenos SaaS. O Vue cuida da interface reativa, e o Go entrega uma API r\u00e1pida que, no final, vira <strong>um \u00fanico bin\u00e1rio<\/strong> com o site dentro. Nesta s\u00e9rie de cinco partes vamos construir, do zero, uma aplica\u00e7\u00e3o de tarefas com login usando <strong>Go, Echo v5 e Vue 3<\/strong>. Todo o c\u00f3digo foi testado nas vers\u00f5es citadas. Nesta primeira parte: o que \u00e9 cada pe\u00e7a, como preparar o ambiente e como subir a primeira rota da API.<\/p>\n<p><!-- more --><\/p>\n<h2>O que vamos construir<\/h2>\n<p>No fim da s\u00e9rie, voc\u00ea ter\u00e1:<\/p>\n<ul>\n<li>uma API JSON em Go com o framework <a href=\"https:\/\/echo.labstack.com\/\">Echo<\/a> v5: login, logout, usu\u00e1rio atual e um CRUD de tarefas;<\/li>\n<li>um frontend em <a href=\"https:\/\/vuejs.org\/\">Vue 3<\/a> com <a href=\"https:\/\/vite.dev\/\">Vite<\/a> e <a href=\"https:\/\/router.vuejs.org\/\">Vue Router<\/a>, com tela de login e lista de tarefas;<\/li>\n<li>sess\u00e3o em cookie <code>HttpOnly<\/code>, sem guardar token no <code>localStorage<\/code>;<\/li>\n<li>o frontend compilado <strong>embutido no bin\u00e1rio Go<\/strong> com <code>go:embed<\/code>;<\/li>\n<li>um <code>Dockerfile<\/code> que compila tudo sem voc\u00ea instalar Go ou Node na m\u00e1quina, e gera uma imagem de cerca de 10 MB.<\/li>\n<\/ul>\n<p>O roteiro da s\u00e9rie:<\/p>\n<ol>\n<li><strong>Ambiente e primeira API<\/strong> (este artigo);<\/li>\n<li><strong>Frontend Vue com Vite<\/strong>, com proxy para a API em desenvolvimento;<\/li>\n<li><strong>API REST de tarefas<\/strong>: rotas, JSON, valida\u00e7\u00e3o e erros no Echo v5;<\/li>\n<li><strong>Login com sess\u00e3o e cookie<\/strong>, middleware de autentica\u00e7\u00e3o e rotas protegidas no Vue Router;<\/li>\n<li><strong>Embed, bin\u00e1rio \u00fanico e Docker<\/strong>: build de produ\u00e7\u00e3o, systemd e Nginx.<\/li>\n<\/ol>\n<h2>Por que Echo v5<\/h2>\n<p>O Echo \u00e9 um framework web minimalista para Go: roteador r\u00e1pido, grupos de rotas, middlewares prontos (log, recover, CORS, arquivos est\u00e1ticos, rate limit) e helpers para JSON. A <strong>vers\u00e3o 5<\/strong> \u00e9 uma quebra de compatibilidade em rela\u00e7\u00e3o \u00e0 v4. As mudan\u00e7as que mais aparecem no dia a dia s\u00e3o:<\/p>\n<ul>\n<li><strong><code>echo.Context<\/code> virou struct:<\/strong> o handler agora recebe <code>*echo.Context<\/code> (ponteiro), n\u00e3o mais a interface <code>echo.Context<\/code>;<\/li>\n<li><strong>log com <code>log\/slog<\/code>:<\/strong> o logger pr\u00f3prio da v4 saiu, e o Echo usa o logger estruturado da biblioteca padr\u00e3o;<\/li>\n<li><strong>novo import:<\/strong> <code>github.com\/labstack\/echo\/v5<\/code>;<\/li>\n<li>m\u00e9todos de rota retornam <code>RouteInfo<\/code>, e o servidor ganhou o <code>echo.StartConfig<\/code> com desligamento gracioso por <code>context<\/code>.<\/li>\n<\/ul>\n<p>Muito tutorial na internet ainda mostra c\u00f3digo da v4, com <code>func(c echo.Context) error<\/code>. Com a v5 esse c\u00f3digo n\u00e3o compila. A lista completa de mudan\u00e7as est\u00e1 no documento <a href=\"https:\/\/github.com\/labstack\/echo\/blob\/master\/API_CHANGES_V5.md\">API_CHANGES_V5.md<\/a> do projeto. Nesta s\u00e9rie usamos o <strong>Echo v5.3.1<\/strong>, publicado em julho de 2026.<\/p>\n<h2>Vers\u00f5es usadas na s\u00e9rie<\/h2>\n<p>Conferidas em 22 de setembro de 2026:<\/p>\n<ul>\n<li><strong>Go 1.27.1<\/strong>;<\/li>\n<li><strong>Node.js 24<\/strong> (LTS), que traz o <code>npm<\/code>;<\/li>\n<li><strong>Echo v5.3.1<\/strong>;<\/li>\n<li><strong>Vue 3.5.43<\/strong>, <strong>Vue Router 4.6.4<\/strong> e <strong>Vite 8.3.0<\/strong>.<\/li>\n<\/ul>\n<p>Vers\u00f5es mais novas dentro da mesma linha devem funcionar. Se algo n\u00e3o compilar, compare primeiro a vers\u00e3o do Echo: \u00e9 a pe\u00e7a com mais mudan\u00e7as entre vers\u00f5es maiores.<\/p>\n<h2>Instale o Go e o Node.js<\/h2>\n<p>Para o Go, use o tarball oficial de <a href=\"https:\/\/go.dev\/dl\/\">go.dev\/dl<\/a>. O pacote das distribui\u00e7\u00f5es costuma estar atrasado, e o Echo v5 exige um Go recente. Temos um guia mais longo em <a href=\"\/2017\/05\/instalando-golang-no-linux\/\">Instalando Golang no Linux<\/a>; o resumo para <code>amd64<\/code>:<\/p>\n<pre><code class=\"language-bash\">curl -LO https:\/\/go.dev\/dl\/go1.27.1.linux-amd64.tar.gz\nsudo rm -rf \/usr\/local\/go\nsudo tar -C \/usr\/local -xzf go1.27.1.linux-amd64.tar.gz\necho 'export PATH=$PATH:\/usr\/local\/go\/bin:$HOME\/go\/bin' &gt;&gt; ~\/.bashrc\nsource ~\/.bashrc\ngo version<\/code><\/pre>\n<p>Para o Node.js, siga a p\u00e1gina oficial de <a href=\"https:\/\/nodejs.org\/en\/download\">download<\/a> e escolha a linha 24 LTS, pelo instalador que preferir (tarball, gerenciador de vers\u00f5es ou reposit\u00f3rio da distribui\u00e7\u00e3o). Depois confira:<\/p>\n<pre><code class=\"language-bash\">node -v    # v24.x\nnpm -v<\/code><\/pre>\n<p>Na parte 5 mostramos como compilar tudo s\u00f3 com Docker. Se preferir n\u00e3o instalar Go e Node, d\u00e1 para acompanhar a s\u00e9rie lendo o c\u00f3digo e deixar o build para o cont\u00eainer.<\/p>\n<h2>Estrutura do projeto<\/h2>\n<p>O backend e o frontend ficam no mesmo reposit\u00f3rio. O Go \u00e9 o projeto principal, e o Vue vive na pasta <code>web\/<\/code>:<\/p>\n<pre><code class=\"language-text\">vueapp\/\n\u251c\u2500\u2500 go.mod\n\u251c\u2500\u2500 main.go              # servidor Echo\n\u251c\u2500\u2500 internal\/api\/        # rotas, login e tarefas (partes 3 e 4)\n\u2514\u2500\u2500 web\/                 # projeto Vue criado pelo Vite (parte 2)\n    \u251c\u2500\u2500 embed.go         # go:embed do build (parte 5)\n    \u251c\u2500\u2500 src\/\n    \u2514\u2500\u2500 dist\/            # gerado pelo npm run build<\/code><\/pre>\n<p>Crie a pasta e o m\u00f3dulo Go. O caminho do m\u00f3dulo \u00e9 o nome usado nos imports; troque pelo endere\u00e7o do seu reposit\u00f3rio:<\/p>\n<pre><code class=\"language-bash\">mkdir vueapp &amp;&amp; cd vueapp\ngo mod init github.com\/exemplo\/vueapp\ngo get github.com\/labstack\/echo\/v5@v5.3.1<\/code><\/pre>\n<h2>A primeira rota com Echo v5<\/h2>\n<p>Crie o <a href=\"https:\/\/gist.github.com\/jniltinho\/c95a0e7bbad4afe779cf143674cbef08#file-main-go\"><code>main.go<\/code><\/a> com uma rota de sa\u00fade em <code>\/api\/health<\/code>. Todas as rotas da API v\u00e3o come\u00e7ar com <code>\/api<\/code>: isso deixa o resto dos caminhos livre para o Vue, o que vai importar nas partes 2 e 5.<\/p>\n<pre><code class=\"language-go\">package main\n\nimport (\n\t\"log\/slog\"\n\t\"net\/http\"\n\n\t\"github.com\/labstack\/echo\/v5\"\n\t\"github.com\/labstack\/echo\/v5\/middleware\"\n)\n\nfunc main() {\n\te := echo.New()\n\te.Use(middleware.RequestLogger())\n\te.Use(middleware.Recover())\n\n\te.GET(\"\/api\/health\", func(c *echo.Context) error {\n\t\treturn c.JSON(http.StatusOK, map[string]string{\"status\": \"ok\"})\n\t})\n\n\tif err := e.Start(\"127.0.0.1:8080\"); err != nil {\n\t\tslog.Error(\"servidor\", \"error\", err)\n\t}\n}<\/code><\/pre>\n<p>O que cada parte faz:<\/p>\n<ul>\n<li><code>echo.New()<\/code> cria a aplica\u00e7\u00e3o;<\/li>\n<li><code>middleware.RequestLogger()<\/code> registra cada requisi\u00e7\u00e3o em JSON via <code>slog<\/code>;<\/li>\n<li><code>middleware.Recover()<\/code> transforma um <code>panic<\/code> num erro 500, em vez de derrubar o processo;<\/li>\n<li>o handler recebe <code>*echo.Context<\/code>, com ponteiro, que \u00e9 a assinatura da v5;<\/li>\n<li><code>c.JSON<\/code> serializa o mapa e define o <code>Content-Type<\/code>.<\/li>\n<\/ul>\n<p>Rode e teste em outro terminal:<\/p>\n<pre><code class=\"language-bash\">go mod tidy\ngo run .<\/code><\/pre>\n<pre><code class=\"language-bash\">curl -i http:\/\/127.0.0.1:8080\/api\/health<\/code><\/pre>\n<pre><code class=\"language-text\">HTTP\/1.1 200 OK\nContent-Type: application\/json\n...\n{\"status\":\"ok\"}<\/code><\/pre>\n<p>No terminal do servidor aparece o banner do Echo e uma linha de log por requisi\u00e7\u00e3o, j\u00e1 em JSON:<\/p>\n<pre><code class=\"language-text\">{\"level\":\"INFO\",\"msg\":\"Echo (v5.3.1). High performance, minimalist Go web framework https:\/\/echo.labstack.com\",\"version\":\"5.3.1\"}\n{\"level\":\"INFO\",\"msg\":\"http(s) server started\",\"address\":\"127.0.0.1:8080\"}\n{\"level\":\"INFO\",\"msg\":\"REQUEST\",\"method\":\"GET\",\"uri\":\"\/api\/health\",\"status\":200,...}<\/code><\/pre>\n<p>Ligamos o servidor em <code>127.0.0.1<\/code> de prop\u00f3sito: durante o desenvolvimento, a API n\u00e3o fica exposta na rede. Na parte 5 a porta e o endere\u00e7o passam a vir de vari\u00e1veis de ambiente.<\/p>\n<h2>Arquivos desta parte no gist<\/h2>\n<p>Cada arquivo abre direto no <a href=\"https:\/\/gist.github.com\/jniltinho\/c95a0e7bbad4afe779cf143674cbef08\">gist da s\u00e9rie<\/a>. O gist traz a <strong>vers\u00e3o final<\/strong> do projeto: <code>main.go<\/code> e <code>routes.go<\/code> ainda ganham login na parte 4 e o frontend embutido na parte 5.<\/p>\n<ul>\n<li><a href=\"https:\/\/gist.github.com\/jniltinho\/c95a0e7bbad4afe779cf143674cbef08#file-main-go\"><code>main.go<\/code><\/a><\/li>\n<li><a href=\"https:\/\/gist.github.com\/jniltinho\/c95a0e7bbad4afe779cf143674cbef08#file-go-mod\"><code>go.mod<\/code><\/a><\/li>\n<\/ul>\n<h2>Pr\u00f3ximo passo<\/h2>\n<p>Com o Go servindo JSON, a <a href=\"\/2026\/09\/vue-go-echo-v5-parte-2-frontend-vue-com-vite\/\">parte 2<\/a> cria o frontend Vue com Vite dentro de <code>web\/<\/code> e configura o proxy que faz o <code>npm run dev<\/code> conversar com esta API sem nenhum problema de CORS. Se voc\u00ea quer ver essa mesma arquitetura aplicada a um projeto maior, leia tamb\u00e9m a s\u00e9rie <a href=\"\/2026\/09\/phpvirtualbox-em-go-parte-1-echo-vue-e-binario-unico\/\">phpVirtualBox em Go<\/a>.<\/p>\n<p><strong>S\u00e9rie Vue.js + Go com Echo v5:<\/strong> <a href=\"\/2026\/09\/vue-go-echo-v5-parte-1-ambiente-e-primeira-api\/\">Parte 1: ambiente e primeira API<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-2-frontend-vue-com-vite\/\">Parte 2: frontend Vue com Vite<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-3-api-rest-de-tarefas\/\">Parte 3: API REST de tarefas<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-4-login-com-sessao-e-cookie\/\">Parte 4: login com sess\u00e3o e cookie<\/a> \u00b7 <a href=\"\/2026\/09\/vue-go-echo-v5-parte-5-embed-binario-unico-e-docker\/\">Parte 5: embed, bin\u00e1rio \u00fanico e Docker<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Series about Vue 3 and Go with Echo v5: what changes in Echo v5, how to install Go and Node, and how to bring up the first API route.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[45,2],"tags":[424,58,31,468],"class_list":["post-1640","post","type-post","status-publish","format-standard","hentry","category-desenv","category-linux","tag-api","tag-go","tag-golang","tag-vue"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1640","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/comments?post=1640"}],"version-history":[{"count":2,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1640\/revisions"}],"predecessor-version":[{"id":1655,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/1640\/revisions\/1655"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/media?parent=1640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/categories?post=1640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/tags?post=1640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}