Quando desenvolvemos aplicações web, lidamos frequentemente com acentos, cedilhas e caracteres especiais da nossa língua (como em "Aprovado(a)" ou "Recuperação"). Nesta aula, vamos entender o conceito de Charset e como configurá-lo na nossa API para garantir que as respostas sejam exibidas perfeitamente em qualquer sistema ou navegador.
O termo Charset vem de Character Set (Conjunto de Caracteres). Ele funciona como uma tabela de tradução que diz ao computador como transformar os códigos binários (zeros e uns) salvos no servidor nos caracteres de texto legíveis que vemos na tela.
O padrão mais utilizado e recomendado no mundo inteiro para a web é o UTF-8. Ele consegue representar praticamente todos os caracteres de quase todas as línguas escritas do planeta, ocupando pouco espaço de memória.
Se nós não informarmos ao cliente (navegador ou aplicativo mobile) qual codificação estamos usando, ele tentará adivinhar ou usará o padrão do sistema operacional dele. Isso pode fazer com que palavras acentuadas retornem quebradas, exibindo aqueles símbolos estranhos e ilegíveis (como Recuperao em vez de Recuperação).
Para resolver isso de forma profissional, adicionamos a instrução charset=utf-8 junto à definição do nosso tipo de conteúdo (Content-Type) no cabeçalho da resposta.
Abra o seu arquivo main.go e modifique as funções listarAlunos e cadastrarAluno para incluir a especificação de charset no cabeçalho. Veja como o código completo do projeto deve ficar estruturado:
// Pacote principal da aplicação
package main
// Importações
import (
"encoding/json"
"fmt"
"net/http"
"github.com/google/uuid"
)
// Modelo (Struct)
type Aluno struct {
Codigo string `json:"codigo"`
Nome string `json:"nome"`
Nota1 float64 `json:"nota1"`
Nota2 float64 `json:"nota2"`
Media float64 `json:"media"`
Situacao string `json:"situacao"`
}
// Slice (Nosso banco de dados em memória)
var alunos = []Aluno{}
// Função para gerar a média e a situação
func mediaSituacao(aluno *Aluno) {
// Gerar média
aluno.Media = (aluno.Nota1 + aluno.Nota2) / 2
// Gerar situação
if aluno.Media >= 7 {
aluno.Situacao = "Aprovado(a)"
} else if aluno.Media >= 5 {
aluno.Situacao = "Em Recuperação"
} else {
aluno.Situacao = "Reprovado(a)"
}
}
// Função para retornar um Hello World! (Mantida para testes temporários)
func helloWorld(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
codigoUnico := uuid.New().String()
mensagem := map[string]string{
"codigoUnico": codigoUnico,
"mensagem": "Hello World!",
}
json.NewEncoder(w).Encode(mensagem)
}
// Função responsável pela listagem de alunos
func listarAlunos(w http.ResponseWriter, r *http.Request) {
// Definir o cabeçalho adicionando explicitamente a codificação UTF-8
w.Header().Set("Content-Type", "application/json; charset=utf-8")
// Definir o Status Code
w.WriteHeader(http.StatusOK)
// Retorna uma lista contendo todos os alunos cadastrados
json.NewEncoder(w).Encode(alunos)
}
// Função responsável pelo cadastro de um aluno
func cadastrarAluno(w http.ResponseWriter, r *http.Request) {
// Definir o cabeçalho adicionando explicitamente a codificação UTF-8
w.Header().Set("Content-Type", "application/json; charset=utf-8")
// Objeto do tipo Aluno
var aluno Aluno
// Decodificar JSON recebido
erro := json.NewDecoder(r.Body).Decode(&aluno)
if erro != nil {
http.Error(w, "Falha ao decodificar o JSON", http.StatusBadRequest)
return
}
// Gerar o código do aluno
aluno.Codigo = uuid.New().String()
// Gerar a média e a situação
mediaSituacao(&aluno)
// Cadastrar no Slice
alunos = append(alunos, aluno)
// Definir o Status Code
w.WriteHeader(http.StatusCreated)
// Retorna o aluno cadastrado
json.NewEncoder(w).Encode(aluno)
}
// Função principal
func main() {
// Rotas
http.HandleFunc("GET /", helloWorld)
http.HandleFunc("GET /alunos", listarAlunos)
http.HandleFunc("POST /alunos", cadastrarAluno)
// Retornar o funcionamento do servidor
fmt.Println("Servidor em execução no endereço: http://localhost:8080")
// Configurar servidor
http.ListenAndServe(":8080", nil)
}
Utilizando o seu cliente HTTP (Postman, Thunder Client ou Insomnia), realize um novo cadastro enviando notas que deixem o aluno com a situação "Em Recuperação". No cabeçalho da resposta (seção Headers), você poderá notar o campo Content-Type preenchido exatamente com application/json; charset=utf-8, garantindo a exibição perfeita dos acentos!