Como gerar documentos do seu código em Go?

Como gerar documentos do seu código em Go?

H√° algum tempo atr√°s, visando manter meu estilo generalista, mergulhei nos estudos de Go. Estava estudando, mas nunca tive a oportunidade de experimentar um projeto em produ√ß√£o para ajustar o treino ao jogo ‚öĹ.

Durante essa jornada tive o prazer e o impacto de conhecer diferentes t√©cnicas para resolver um problema. Sem d√ļvidas, me apeguei ao conceito da linguagem e decidi trocar uma aplica√ß√£o pessoal que fiz em Elixir para Go. O objetivo deste artigo n√£o √© comparar ūüę°, esse √© um coment√°rio para demonstrar o quanto cheguei √† produtividade e maturidade que eu esperava.

Godoc

Deixando de lado as compara√ß√Ķes! Assim como o Pyhton possui o pydoc, o Node.js possui o ESDoc. O Go tamb√©m disponibiliza o pacote godoc para extra√ß√£o de documenta√ß√£o, o qual converte todos os coment√°rios estruturados em uma vers√£o HTML.

Sempre gostei dessa abordagem. Eu pessoalmente n√£o vejo problemas entre o c√≥digo e a documenta√ß√£o. Devemos nos lembrar que, assim como o Chat GPT, produzimos c√≥digos para outros seres humanos. Por √ļltimo, √© importante manter a documenta√ß√£o atualizada.

O estilo de documentação é simplificado e sem muitas regras, deixando que você defina a sua forma de documentar os argumentos da função e seu retorno.

Bora para a pr√°tica!

Iremos criar uma simples aplica√ß√£o http documentada que devolve dados de cart√Ķes aleat√≥rios para o super hacker da gera√ß√£o, que usa a palavra "hack" para tudo, poder realizar transa√ß√Ķes e receber uma compra negada na sua cara.

O super hacker

Dependências

Iremos instalar duas bibliotecas oficiais o godoc e o pkgsite, que permitem a convers√£o dos coment√°rios para HTML.

go install -v golang.org/x/tools/cmd/godoc@latest
go install golang.org/x/pkgsite/cmd/pkgsite@latest

Códigos

  • go.mod
ūüí¨ O pacote gofakeit oferece diversas implementa√ß√Ķes para gerar informa√ß√Ķes aleat√≥rias, o que torna a prepara√ß√£o de ambientes de teste e fixtures mais f√°cil.
module github.com/williampsena/go-recipes/doc-app-example

go 1.22.4

require github.com/brianvoe/gofakeit/v7 v7.0.3 // indirect

  • main.go
// This package represents the application command for starting a web server.
package main

import (
	"github.com/brianvoe/gofakeit/v7"
	"github.com/williampsena/go-recipes/doc-app-example/web"
)

// This function is responsible for setting up the program before it runs
func init() {
	gofakeit.Seed(0)
}

// Application entrypoint
func main() {
	svr := web.BuildServer()
	web.ListenAndServe(svr)
}
  • Makefile
SHELL=bash

dev:
	go run main.go

docs-godoc:
	godoc -http=:4444

docs-pkgsite:
	pkgsite -http=:4444
  • web/server.go
// This package contains web server structures and functions responsible for handling HTTP application.
package web

import (
	"fmt"
	"net/http"
)

// Create an application web server mux with routes established
func BuildServer() *http.ServeMux {
	mux := http.NewServeMux()

	mux.HandleFunc("GET /health", HealthCheckEndpoint)
	mux.HandleFunc("GET /cards", CardGeneratorEndpoint)

	return mux
}

// Listening web server on port 4000
func ListenAndServe(mux *http.ServeMux) {
	fmt.Println("‚úÖ The sever is listening at port 4000")
	http.ListenAndServe("localhost:4000", mux)
}
  • web/cards.go
package web

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/brianvoe/gofakeit/v7"
)

// Struct responsible for holding all card data, such as the holder's name and card number
type Card struct {
	HolderName string `json:"holder_name"` // card holder name
	Type       string `json:"type"`        // card type (master, visa, amex)
	Number     string `json:"number"`      // card number
	Cvv        string `json:"cvv"`         // card verification code
	Expiration string `json:"exp"`         // the expiration year + month
}

// Create a Fake Card Struct
func BuildCard() (*Card, error) {
	creditCard := gofakeit.CreditCard()

	card := Card{
		HolderName: gofakeit.Name(),
		Type:       creditCard.Type,
		Number:     creditCard.Number,
		Cvv:        creditCard.Cvv,
		Expiration: creditCard.Exp,
	}

	return &card, nil
}

// Endpoint is responsible for responding to a false card generation
func CardGeneratorEndpoint(w http.ResponseWriter, r *http.Request) {
	card, err := BuildCard()

	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprint(w, "Sorry, something wrong happened!")
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(card)
}

  • web/health.go
package web

import (
	"fmt"
	"net/http"
)

// Endpoint is responsible for responding to application health
func HealthCheckEndpoint(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "I'm so healthy ūüėĆ!")
}
O propósito do artigo não é detalhar cada aspecto da implementação, mas sim examinar os comentários inseridos no código que serão traduzidos para a documentação HTML.

Vamos executar a aplica√ß√£o super hacker ūüíÄ que gera informa√ß√Ķes de cart√Ķes ūüí≥.

make dev

# ou

go run main.go

A aplicação estará acessível na porta 4000, é possível executar os comandos a seguir para verificar suas rotas:

curl http://localhost:4000/health 

# I'm so healthy ūüėĆ!

curl http://localhost:4000/cards 

# {"holder_name":"Ephraim Hand","type":"American Express" "number":"6062825121549507","cvv":"857","exp":"08/25"}

Gerar documentação

Com a estrutura do projeto pronta, executaremos o godoc para verificar a documentação gerada.

make docs-godoc

# ou

godoc -http=:4444

A documentação está acessível na porta 4444.

Bom, como vocês podem ver no vídeo acima, a navegação não ficou tão objetiva como gostaríamos, certo?

Assim, se um pacote não atende aos gostos populares, essa nova geração cria um novo, correto (vide NPM packages)? O pkgsite possui uma documentação mais estruturada, com uma melhor experiência de navegação do que a do godoc, utilizada como frontend dos pacotes Go. Encontrei uma referências que indica um movimento de "deprecated" do godoc em favor do uso do pkgsite.

Sem mais delongas! Vamos agora ao pkgsite, nada precisa ser ajustado somente instalar e executar o pacote.

√Č hora de visualizar uma documenta√ß√£o com uma melhor experi√™ncia de navega√ß√£o.

make docs-pkgsite

# ou

pkgsite -http=:4444

A documentação está acessível na porta 4444.

Como podemos perceber, a diferen√ßa come√ßa nas cores do tema. Muitas pessoas amam o dark-mode, confesso que gosto de algumas aplica√ß√Ķes no light, n√£o me julgem. A leitura do c√≥digo no modo (raw) facilita o nosso copy/paste ūüėú. Fato o pkgsite tem uma experi√™ncia de navega√ß√£o superior.

Repositório

A implementação está disponível em meu repositório do Github:

go-recipes/doc-app-example at main · williampsena/go-recipes
Contribute to williampsena/go-recipes development by creating an account on GitHub.

Fim!

Por hoje √© s√≥, espero que o conte√ļdo possa aprimoar suas experi√™ncias em Go, mantenham o ūü߆ kernel atualizado, com tudo que seja respeit√°vel, justo, puro e de boa fama, se h√° alguma virtude ou louvor que isso habite em nossos pensamentos! ūüēäÔłŹ Filipenses 4:8

Referências