Golang: como ler um arquivo json
Neste artigo, Marcela Sisiliani apresenta uma estrutura de um programa em Golang, através de uma POC que vai ler um arquivo em json, consumir os dados na nossa aplicação em GO Programming Language e salvar em um novo arquivo.

Na web, o JSON é conhecido como um dos principais formatos de reapresentação de dados, e sua fama se dá ao fato de ele ser leve (compare com o formato XML pra ver), simples e compacto, facilitando o parsing das informações pela aplicação.
A verdade é que já existem muitas formas de ler um arquivo JSON usando o golang, mas hoje vamos restringir o nosso estudo a um parsing usando apenas o pacotes da biblioteca padrão da linguagem (o GO tem milhares de pacotes ‘nativos’, por assim dizer, que facilitam nossa vida mantendo o programa leve).
Vamos lá!
Pré-requisitos: vamos partir do pressuposto de que você já esteja ciente da instalação do GO em sua máquina, beleza? Caso não tenha instalado ainda, dê uma olhada nesses artigos bacanas:
Ou ainda na documentação oficial que – pasmem – está em português, e faça a instalação antes de começarmos.
Passo 1 – Ferramentas
Para esse artigo vamos usar as seguintes ferramentas:
- GO Versão 1.12+ (na minha máquina é essa, mas você pode utilizar a versão mais atual também)
- Visual Code
- Packages GO: digitar a instrução go get para baixar os pacotes
Passo 2 – Estrutura de um programa em GO
Os programas em GO devem ser criados dentro da pasta source, definida na instalação, que por padrão é “C:\Users\nome-do-seu-usuario\go\src”. Dentro dessa pasta vamos criar uma pasta chamada go-read-json-file.
Todo programa em go precisa de um arquivo inicial, conhecido como main, que vai ser executado ao inicializarmos a aplicação.
Aqui vamos exemplificar com esse arquivo, mas todo arquivo em go tem basicamente a mesma estrutura, que é essa abaixo:
Estrutura dos arquivos em Go
package main //nome do package. Como estamos na raiz do programa o nome da package será "main"
import (
//Declaração de todos os pacotes que serão utilizados nesse arquivo
)
func main() {
//Instruções iniciais da aplicação.
}Pois bem, vamos entrar dentro dessa pasta a partir do Visual Studio Code e criar um novo arquivo chamado main.go, onde vai ficar todo nosso código.
Passo 3 – Conhecendo a estrutura do JSON
Vamos trabalhar com um objeto bem simples (por enquanto, muHAhaAHhah), que vai conter algumas propriedades de um objeto livro, conforme apresentado no trecho abaixo:
{
"name":"Programando em Go: Crie aplicações com a linguagem do Google",
"publisher":"Casa do código",
"author": "Caio Filipini",
"link":"https://www.casadocodigo.com.br/products/livro-google-go"
}Passo 4 – Criando o objeto em GO
Para converter essa estrutura JSON para uma struct – é assim que chamamos classes em GO – podemos usar a ferramenta JSON-to-Go.
Basta colar o json lá que ela converte para o formato de classe do GO rapidinho, precisando apenas ajustar seu nome ou quebrar em mais structs, se necessário.
Book: nossa primeira struct
type Book struct {
Name string `json:"name"`
Publisher string `json:"publisher"`
Author string `json:"author"`
Link string `json:"link"`
}Passo 5 – Abrindo o arquivo JSON
Pacotes
Aqui vamos usar a função Open do pacote nativo os. Para utilizarmos os pacotes no Golang basta importarmos o pacote através da instrução abaixo:
Exemplos de imports em golang
import (
"nome_do_pacote" //pacote nativo
"https://github.com/user/nome_do_pacote" //pacote da comunidade - endereço completo do pacote
)Aqui nessa POC vamos trabalhar apenas com pacotes nativos, conforme a imagem abaixo:
Import dos pacotes nativos que vamos usar
import (
"fmt"
"io/ioutil"
"os"
"encoding/json"
)No trecho abaixo estamos abrindo nosso arquivo JSON através da função os.Open, que além de retornar o arquivo jsonFile, retorna um objeto do tipo error, para que seja possível verificar se houve algum erro na abertura do arquivo:
jsonFile, err := os.Open(`book.json`)Error
É sempre importante verificar se ocorreram erros durante a execução do nosso programa. Aqui vamos fazer uma verificação simples, apenas apresentando o erro na tela, caso ocorra o erro. Conforme a instrução a seguir:
if err != nil {
//Caso tenha tido erro, ele é apresentado na tela
fmt.Println(err)
}Esse trecho será usado sempre que as funções retornarem erros para podermos realizar alguma tratativa em relação a eles.
Dispose e Defer
Uma boa prática é sempre fechar, ou dar dispose, nos objetos que utilizamos, para não ocuparmos memória, tão pouco recursos de I/O, desnecessários durante a execução do programa.
Algumas linguagens possuem um funcionalidade chamada em geral de “Garbage Collector”, que é um tipo de lixeiro que passa de vez em quando para limpar a memória. O GO também possui esse recurso para gerenciar a memória.
Contudo, não existe essa funcionalidade para a gestão de recursos de I/O, como conexão de rede, conexão de banco de dados ou arquivos físicos. Para fazer isso temos um instrução que auxilia nessa finalidade: o defer. Essa instrução é executada no fim de cada função com o bloco de código que inserirmos. Com o código abaixo fechamos o arquivo “jsonFile” ao fim da função.
defer jsonFile.Close()Passo 6 – Decodificando o JSON para nosso objeto
Para conseguir manipular o nosso json dentro de um objeto Book, vamos precisar transformar nosso arquivo primeiro em um array de bytes para depois utilizar a função json.Unmarshal para transformar os bytes em um objeto Book. No código é exatamente o que estamos fazendo.
//Aqui o arquivo é convertido para uma variável array de bytes, através do pacote "io/ioutil"
byteValueJSON, _:= ioutil.ReadAll(jsonFile)
//Declaração abreviada de um objeto do tipo Book
objBook := Book{}
//Conversão da variável byte em um objeto do tipo struct Book
json.Unmarshal(byteValueJSON, &objBook)Passo 7 – Alterando o objeto Book
A alteração de uma propriedade em GO é super simples e parecida com muitas linguagens. Basta usar a instrução “nome_do_objeto.nome_da_propriedade”. Segue um exemplo para alterarmos e vermos a alteração da propriedade no console:
Antes e depois da propriedade Name do objeto objBook
//Apresentação na tela do campo Name
fmt.Println(objBook.Name)
//Alteração do campo Name
objBook.Name = "New book name"
//Apresentação no console do novo valor do campo Name
fmt.Println(objBook.Name) Vamos executar o programa agora pra ver essa alteração no console. Para isso, digite a seguinte alteração no console: go run main.go.

Passo 8 – Salvando em um arquivo JSON
Agora, para finalizar com chave de ouro, vamos salvar nossa struct alterada em um novo arquivo? Vamos!
Para isso basta converter o objeto objBook para um array de bytes usando a função json.Marshal, e depois, através da função ioutil.WriteFile, salvar em um novo arquivo.
//Aqui vamos converter nosso objBook com o nome alterado em bytes
byteValueJSON, err = json.Marshal(objBook)
if err != nil {
fmt.Println(err)
}
//Por fim vamos salvar em um arquivo JSON alterado.
err = ioutil.WriteFile("newBook.json", byteValueJSON, 0644)
if err != nil {
fmt.Println(err)
}Usei o nome newBook.json para não sobrescrever o arquivo original. Sempre que executar sua aplicação, o arquivo newBook.json será sobrescrito.

Extras
Se quiser se aprofundar nos packages de manipulação de json, dê uma olhada nesses links:
- How to access deeply nested JSON data using Go (lang)?
- JSON Schema And Go
- Query JSON data using Golang (gojsonq)
E fim! Sua primeira aplicação em GO está finalizada! Caso queira consultar o código, subi um repo no GIT com a solução (com o comentário de cada linha de código).
Espero que tenha ajudado, e se tiver alguma dúvida ou sugestão, deixe nos comentários.
Até mais!








