DEV Community

João Vanzuita
João Vanzuita

Posted on

1 2

Gerando Especificação OpenAPI com Go Lang e Swagger

OpenAPI é uma padrão de especificação de API, criado de maneira a facilitar o processo de desenvolvimento
e o entendimento do que a API realiza, de uma maneira simples em que programadores e utilizadores
da API possam ler, utilizar e experimentar o seu funcionamento de forma simples e rápida.

O Http Swagger é um wrapper para automatizar a geração de especificação de API utilizando Swagger
versão 2.0.

Os principais PROs gerando a documentação da API dessa forma são:

  • approach documentação como código.
  • a documentação fica próxima da função que a utiliza, qualquer dúvida ou atualização, o que precisa ser consultado e atualizado estão próximos.
  • Em Go Lang, se algo está errado, o código não compila. Em outras palavras, se a definição da API estiver errada, eu logo noto e posso rapidamente corrigi-la.

Mão na massa!

1. O primeiro passo é iniciar o projeto:

mkdir seu-projecto
cd $_
go mod init github.com/<seu-user>/seu-projeto
Enter fullscreen mode Exit fullscreen mode

2. Inicie a API básica

Nesse exemplo crio duas funções, um endpoint GET e outro POST.

2.1 Endpoint básico para mostrar a versão da sua API

Utilizo o router Chi, porque preciso definir os verbos GET e POST
no router, e não somente verificar o verbo na função. Por exemplo, tenho um endpoint fictício [GET] /teste, neste endpoint definimos a especificacão
OpenAPI para este endpoint, quando quero um verbo [POST] para a mesma entidade, eu preciso de um
router p/ definir qual função é responsável pelo [GET] e qual função é responsável pelo [POST],
vou mostrar isso, na prática, um pouco mais a frente.

func main() {
    r := chi.NewRouter()
    r.Get("/", version)
    fmt.Println("API listening at port 3001...")
    err := http.ListenAndServe(":3001", r)
    if err != nil {
        log.Fatal(err)
    }
}
Enter fullscreen mode Exit fullscreen mode

P/ informar a minha API que uma especificação OpenAPI será criada, preciso criamos um endpoint chamado
/swagger, e definimos a espcificacão inicial. Neste endpoint /swagger a documentação auto gerada
estará disponível usando a UI do Swagger. P/ isso defino este endpoint na API da seguinte forma:

r.Get("/swagger/*", httpSwagger.WrapHandler)
Enter fullscreen mode Exit fullscreen mode

E adiciono a especificação OpenAPI p/ a função main, que ficará:

// @title Titulo da sua API
// @version 1.0
// @description Descricão longa da sua API
// @termsOfService http://swagger.io/terms/
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:3001
// @BasePath /
func main() {
    r := chi.NewRouter()
    r.Get("/", version)
    r.Get("/swagger/*", httpSwagger.WrapHandler)
    fmt.Println("API listening at port 3001...")
    err := http.ListenAndServe(":3001", r)
    if err != nil {
        log.Fatal(err)
    }
}
Enter fullscreen mode Exit fullscreen mode

Agora defino o exemplo p/ o endpoint [GET] / sem a especificação OpenAPI:

func version(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("version: 1.0.0"))
}
Enter fullscreen mode Exit fullscreen mode

E em seguida defino a especificacão OpenAPI da seguinte forma p/ este endpoint:

// version godoc
// @Summary Get API version
// @Description Get API version
// @Tags version
// @Accept  json
// @Produce  json
// @Success 200 {object} string
// @Router / [get]
Enter fullscreen mode Exit fullscreen mode

2.2 Adicionando os imports necessários

O primeiro import é importante p/ informar onde a minha definição da API está localizada, em seguida
importo o router e o http-swagger que é responsável em ler os comentários e transformar em
especificação no formato OpenAPI.

Primeiro instalo a biblioteca Chi:

go get -u github.com/go-chi/chi/v5
go get -u github.com/swaggo/swag/cmd/swag
go get -u github.com/swaggo/http-swagger
Enter fullscreen mode Exit fullscreen mode

E adiciono os importes:

_ "github.com/converge/strave-stories/docs" // docs is generated by Swag CLI, you have to import it.
"github.com/go-chi/chi/v5"
httpSwagger "github.com/swaggo/http-swagger"
Enter fullscreen mode Exit fullscreen mode

3. Utilizando a ferramenta Swag p/ fazer o parser e gerar a especificação OpenAPI

Neste ponto já posso chamar o Swag, que criará os arquivos necessários, p/ posteriormente
chamarmos o Swagger UI, que é a página web que mostra a documentação que especificamos nos
comentários das funções, e também inicio a API para que a página fique exposta na API.

Então novamente, os passos p/ gerar a documentão e iniciar o Swagger UI são:

swag init
go run main.go
Enter fullscreen mode Exit fullscreen mode

Agora é possível access o Swagger UI através do endereço http://localhost:3001/swagger/

Adicionando endpoint /my-bike para o verbo [GET]

É tão claro e fácil, que agora somente lendo o código é possível identificar como gerar documentação
através dos comentários funciona, e como a OpenAPI é simples e gostosa de trabalhar.

// listMyBike
// @Summary List My Bike
// @Description List details of My Bike
// @Tags listMyBike
// @Accept json
// @Produce json
// @Success 200 {object} Bike
// @Router /my-bike [GET]
func listMyBike(w http.ResponseWriter, r *http.Request) {
err := json.NewEncoder(w).Encode(myBike)
if err != nil {
log.Println(err)
}
}
Enter fullscreen mode Exit fullscreen mode

Adicionando endpoint /my-bike para o verbo [POST]

Seguindo a ideia anterior, esta é a definição p/ o método POST:

// createMyBike
// @Summary Create a Bike
// @Description Create a Bike
// @Tags createMyBike
// @Accept json
// @Produce json
// @param body body Bike true "Bike Object"
// @Success 201 {object} Bike
// @Router /my-bike [POST]
func createMyBike(w http.ResponseWriter, r *http.Request) {
    reqBody, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Println(err)
    }
    defer r.Body.Close()
    json.Unmarshal(reqBody, &myBike)
    if err != nil {
        log.Println(err)
    }
    w.Write([]byte("Bike created!"))
}
Enter fullscreen mode Exit fullscreen mode

Um exemplo completo e funcionando está disponível aqui

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay