Ouvindo aos pedidos da comunidade, mesmo que não incorporado oficialmente ao CLI do Go ainda, o time de desenvolvimento da linguagem Go criou um novo programa capaz de ajudar a iniciar novos projetos. Seu nome, pelo menos por enquanto, gonew.
Como dito no parágrafo anterior, a finalidade desse novo programa é auxiliar na criação de novos projetos Go. Com ele, podemos utilizar um repositório template como base para novas aplicações.
Sem mais delongas, vamos meter a mão na massa, ou melhor, no teclado.
Instalação
Para conseguir utilizar esse novo programa, precisamos tê-lo instalado. A forma mais fácil, já que você muito provavelmente tem o Go instalado na sua máquina, é utilizar o comando go install.
Protocol buffers, protobuf ou simplesmente proto, é uma linguagem criada pela Google para serialização de dados. Para facilitar o entendimento, podemos comparar o protobuf com XML ou JSON. No entanto, dados serializados com proto, são MUITO menores quando comparados com as outras duas tecnologias.
Outro ponto importante é que, após escrever um arquivo proto, utilizamos um programa chamado protoc para gerar código em Go, Java, Python, C#, C, C++, entre outras linguagens. Código esse que contém todas as classes e métodos que estiverem declarados dentro dos arquivos proto.
Mas calma! Antes de falar mais sobre esse código gerado, vamos entender o que compõe e como criar um arquivo proto.
Syntax
A primeira coisa que precisamos fazer em um arquivo proto é definir sua syntax. Essa syntax nada mais é do que a versão do protobuf que iremos utilizar.
Aprender uma nova tecnologia nunca é fácil, pois normalmente ficamos perdidos sobre onde encontrar conteúdo de qualidade. Nesse post, vou listar alguns locais/livros onde vou para estudar e me atualizar sobre nossa querida Golang.
Embora não haja atualizações constantes, você sempre irá encontrar posts importantes e sobre questões complexas, assim como anúncios de releases e pesquisas.
Pode parecer estranho eu recomendar o blog que você está, porém como eu não sei se você chegou até aqui pelo Google, vale dizer que nós postamos conteúdos semanalmente.
Nesses posts abordamos assuntos como, frameworks, benchmarks, tutoriais iniciantes e avançados sobre a linguagem e como algumas partes dela funcionam por debaixo dos panos.
Se você já ouviu falar mas não sabe ao certo o que é Dependency Injection ou como a utilizar em Golang, nesse post espero te ajudar a sanar as duas dúvidas.
Para que todos estejam na mesma página, antes de ver como utilizar, vamos falar um pouco sobre o que é essa tal Dependency Injection ou DI para os íntimos.
Podemos definir DI (Dependency Injection) como uma técnica onde os módulos recebem todas ou parte de suas dependências de forma indireta, ou seja, por parâmetro em uma função/método ou sendo passada diretamente para o campo de uma struct, onde tais parâmetros ou campos não tenham um tipo definido, mas sim uma interface.
Vantagens da Dependency Injection
Utilizar essa técnica ajuda com que nosso código tenha baixo acoplamento, o que torna a tarefa de refatorar partes do sistema muito mais fácil.
Como você deve ter visto no vídeo que postamos no canal, uma das formas de reduzir o tamanho de uma imagem docker para aplicações Go é utilizando a imagem scratch como base.
Mas e o binário? Como podemos reduzi-lo sem remover código?
É isso que vamos ver nesse post.
Para que tenhamos uma base de programa para testar os comandos que vamos ver nesse post, vamos escrever uma API bem simples.
Se você se sente incomodado em ter que parar sua aplicação e fazer go run novamente toda vez que faz uma alteração, esse post vai melhorar sua vida… e MUITO.
Nesse post vou te mostrar como fazer live reload de aplicações Go utilizando uma ferramenta open source chamada Air (https://github.com/cosmtrek/air).
Para testar as funcionalidades da ferramenta, vamos escrever um pequeno programa que retorna um “Olá mundo”.
Vamos inicializar um novo módulo com o comando go mod init github.com/aprendagolang/live-reload e criar um arquivo main.go com o seguinte conteúdo.
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
r.Get("/", func(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte("Olá Mundo"))
})
http.ListenAndServe(":8080", r)
}
Como estamos utilizando uma dependência externa, vamos executar o go mod tidy para atualizar nosso go.mod, que deve ficar parecido com isso:
module github.com/aprendagolang/live-reload
go 1.18
require github.com/go-chi/chi/v5 v5.0.7
Com nosso pequeno programa escrito, vamos instalar o Air.
Por ser escrito em Go, podemos fazer sua instalação utilizando o próprio install do Go.
go install github.com/cosmtrek/air@latest
Para testar se deu tudo certo com a instalação, execute um air -v no seu terminal. Se a instação ocorreu sem problemas, você deverá ver o seguinte output:
Agora vamos criar um arquivo de configuração para o Air com o comando air init. Esse comando irá criar um arquivo chamado .air.toml com o seguinte conteúdo.
Se você não é muito fã de ORMs como eu, um dos problemas que você mais enfrenta é o de como realizar alterações em seu banco de dados de forma segura e automática.
Nesse post, vou mostrar como fazer isso utilizando o Migrate (https://github.com/golang-migrate/migrate), um projeto open source escrito em Go para realizar migrations em bancos de dados.
Antes de começar, embora os exemplos contidos nesse tutorial serem utilizando postgres, o Migrate suporta os seguintes bancos de dados:
Tendo esclarecido esse ponto, vamos iniciar um projeto com nome github.com/aprendagolang/migrate (go mod init github.com/aprendagolang/migrate) e depois escrever uma pequena API.
Se você já trabalhou ou conhece um pouco de outras linguagens, podemos comprar o arquivo go.mod ao package.json do JS, composer.json do PHP ou requirements.txt do Python.
Ou seja, o arquivo go.mod, nada mais é do que o arquivo onde o Go vai gerenciar a lista de pacotes que sua aplicação precisa para funcionar.
Além das dependências, é nesse arquivo onde o Go adiciona o nome do seu package e a versão do Go que estava sendo utilizada no momento da criação do projeto.
Essa segunda informação é muito valiosa, pois com base nela o Go vai saber quais versões das dependências externas ele pode ou não utilizar.
Uma dúvida que tenho visto com certa frequência é sobre as classes e herança em Go.
Sempre lembrando que GO não tem orientação a objetos na sua forma original de ser. Porém, quando o assunto é classe e herança, é possível alcançar algo similar utilizando structs e a técnica de embedding.
Tento esclarecido isso, vamos ver como podemos utilizar “herança” em Go imaginando um banco de dados com 4 tabelas.
Chaining de métodos é uma técnica muito utilizada em linguagens como PHP, Java e C#. Se você não está familiarizado com o termo, não se preocupe, pois essa é uma técnica muito simples. Ela consiste em retornar um objeto para que outro método possa ser chamado sem a necessidade de atribuição a uma outra variável.
Essa técnica é muito utilizada em ORMs como o GORM, para construção de queries mais complexas.
No vídeo que postamos no nosso canal do youtube mostrando como construir uma API completa com go-chi e postgres (link para o vídeo), também podemos ver essa técnica sendo utilizada para fazer o decode da request para uma struct.
Para entender melhor seu funcionamento, vamos criar uma struct com 100% de seus atributos privados.