Vue.js + Go com Echo v5, parte 1: ambiente e primeira API

Mascote LinuxPro programando numa estação com o logo do Vue na tela e o gopher do Go na mesa, com o cachorro caramelo cyborg deitado ao lado

Série Vue.js + Go com Echo v5: Parte 1: ambiente e primeira API · Parte 2: frontend Vue com Vite · Parte 3: API REST de tarefas · Parte 4: login com sessão e cookie · Parte 5: embed, binário único e Docker

Código completo: todos os arquivos da série estão no gist vue-go-echo-v5, com um README que mostra em qual pasta cada um fica.

Um frontend em Vue.js e um backend em Go formam uma dupla muito prática para ferramentas internas, painéis e pequenos SaaS. O Vue cuida da interface reativa, e o Go entrega uma API rápida que, no final, vira um único binário com o site dentro. Nesta série de cinco partes vamos construir, do zero, uma aplicação de tarefas com login usando Go, Echo v5 e Vue 3. Todo o código foi testado nas versões citadas. Nesta primeira parte: o que é cada peça, como preparar o ambiente e como subir a primeira rota da API.

O que vamos construir

No fim da série, você terá:

  • uma API JSON em Go com o framework Echo v5: login, logout, usuário atual e um CRUD de tarefas;
  • um frontend em Vue 3 com Vite e Vue Router, com tela de login e lista de tarefas;
  • sessão em cookie HttpOnly, sem guardar token no localStorage;
  • o frontend compilado embutido no binário Go com go:embed;
  • um Dockerfile que compila tudo sem você instalar Go ou Node na máquina, e gera uma imagem de cerca de 10 MB.

O roteiro da série:

  1. Ambiente e primeira API (este artigo);
  2. Frontend Vue com Vite, com proxy para a API em desenvolvimento;
  3. API REST de tarefas: rotas, JSON, validação e erros no Echo v5;
  4. Login com sessão e cookie, middleware de autenticação e rotas protegidas no Vue Router;
  5. Embed, binário único e Docker: build de produção, systemd e Nginx.

Por que Echo v5

O Echo é um framework web minimalista para Go: roteador rápido, grupos de rotas, middlewares prontos (log, recover, CORS, arquivos estáticos, rate limit) e helpers para JSON. A versão 5 é uma quebra de compatibilidade em relação à v4. As mudanças que mais aparecem no dia a dia são:

  • echo.Context virou struct: o handler agora recebe *echo.Context (ponteiro), não mais a interface echo.Context;
  • log com log/slog: o logger próprio da v4 saiu, e o Echo usa o logger estruturado da biblioteca padrão;
  • novo import: github.com/labstack/echo/v5;
  • métodos de rota retornam RouteInfo, e o servidor ganhou o echo.StartConfig com desligamento gracioso por context.

Muito tutorial na internet ainda mostra código da v4, com func(c echo.Context) error. Com a v5 esse código não compila. A lista completa de mudanças está no documento API_CHANGES_V5.md do projeto. Nesta série usamos o Echo v5.3.1, publicado em julho de 2026.

Versões usadas na série

Conferidas em 22 de setembro de 2026:

  • Go 1.27.1;
  • Node.js 24 (LTS), que traz o npm;
  • Echo v5.3.1;
  • Vue 3.5.43, Vue Router 4.6.4 e Vite 8.3.0.

Versões mais novas dentro da mesma linha devem funcionar. Se algo não compilar, compare primeiro a versão do Echo: é a peça com mais mudanças entre versões maiores.

Instale o Go e o Node.js

Para o Go, use o tarball oficial de go.dev/dl. O pacote das distribuições costuma estar atrasado, e o Echo v5 exige um Go recente. Temos um guia mais longo em Instalando Golang no Linux; o resumo para amd64:

curl -LO https://go.dev/dl/go1.27.1.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.27.1.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc
go version

Para o Node.js, siga a página oficial de download e escolha a linha 24 LTS, pelo instalador que preferir (tarball, gerenciador de versões ou repositório da distribuição). Depois confira:

node -v    # v24.x
npm -v

Na parte 5 mostramos como compilar tudo só com Docker. Se preferir não instalar Go e Node, dá para acompanhar a série lendo o código e deixar o build para o contêiner.

Estrutura do projeto

O backend e o frontend ficam no mesmo repositório. O Go é o projeto principal, e o Vue vive na pasta web/:

vueapp/
├── go.mod
├── main.go              # servidor Echo
├── internal/api/        # rotas, login e tarefas (partes 3 e 4)
└── web/                 # projeto Vue criado pelo Vite (parte 2)
    ├── embed.go         # go:embed do build (parte 5)
    ├── src/
    └── dist/            # gerado pelo npm run build

Crie a pasta e o módulo Go. O caminho do módulo é o nome usado nos imports; troque pelo endereço do seu repositório:

mkdir vueapp && cd vueapp
go mod init github.com/exemplo/vueapp
go get github.com/labstack/echo/v5@v5.3.1

A primeira rota com Echo v5

Crie o main.go com uma rota de saúde em /api/health. Todas as rotas da API vão começar com /api: isso deixa o resto dos caminhos livre para o Vue, o que vai importar nas partes 2 e 5.

package main

import (
	"log/slog"
	"net/http"

	"github.com/labstack/echo/v5"
	"github.com/labstack/echo/v5/middleware"
)

func main() {
	e := echo.New()
	e.Use(middleware.RequestLogger())
	e.Use(middleware.Recover())

	e.GET("/api/health", func(c *echo.Context) error {
		return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
	})

	if err := e.Start("127.0.0.1:8080"); err != nil {
		slog.Error("servidor", "error", err)
	}
}

O que cada parte faz:

  • echo.New() cria a aplicação;
  • middleware.RequestLogger() registra cada requisição em JSON via slog;
  • middleware.Recover() transforma um panic num erro 500, em vez de derrubar o processo;
  • o handler recebe *echo.Context, com ponteiro, que é a assinatura da v5;
  • c.JSON serializa o mapa e define o Content-Type.

Rode e teste em outro terminal:

go mod tidy
go run .
curl -i http://127.0.0.1:8080/api/health
HTTP/1.1 200 OK
Content-Type: application/json
...
{"status":"ok"}

No terminal do servidor aparece o banner do Echo e uma linha de log por requisição, já em JSON:

{"level":"INFO","msg":"Echo (v5.3.1). High performance, minimalist Go web framework https://echo.labstack.com","version":"5.3.1"}
{"level":"INFO","msg":"http(s) server started","address":"127.0.0.1:8080"}
{"level":"INFO","msg":"REQUEST","method":"GET","uri":"/api/health","status":200,...}

Ligamos o servidor em 127.0.0.1 de propósito: durante o desenvolvimento, a API não fica exposta na rede. Na parte 5 a porta e o endereço passam a vir de variáveis de ambiente.

Arquivos desta parte no gist

Cada arquivo abre direto no gist da série. O gist traz a versão final do projeto: main.go e routes.go ainda ganham login na parte 4 e o frontend embutido na parte 5.

Próximo passo

Com o Go servindo JSON, a parte 2 cria o frontend Vue com Vite dentro de web/ e configura o proxy que faz o npm run dev conversar com esta API sem nenhum problema de CORS. Se você quer ver essa mesma arquitetura aplicada a um projeto maior, leia também a série phpVirtualBox em Go.

Série Vue.js + Go com Echo v5: Parte 1: ambiente e primeira API · Parte 2: frontend Vue com Vite · Parte 3: API REST de tarefas · Parte 4: login com sessão e cookie · Parte 5: embed, binário único e Docker