Testando o novo mux no GO 1.22
Tags: go, mux, programming, braziliandevs
Published: 2024-01-05 01:32:41

---
title: Testando o novo mux no GO 1.22
published: true
description: Testando o mux http server em Go (Golang) no que será a versão 1.22 (1.22rc1)
tags: go,mux,programming,braziliandevs
# cover_image: https://bolha.photos/storage/m/_v2/623879489199559331/3b17271c9-2ea36d/QphRLw6IwCur/xRALF192OYWX8o8BsNC6ocgVjnblpEtdQ3rnCEh7.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-01-05 01:24 +0000
---

### Motivação

O fato da linguagem *Go* me lembrar muito da linguagem *C* a tornou muito confortável para mim. Em todo o tempo em que estudo a linguagem por hobby, uma coisa me incomoda: o uso de bibliotecas de terceiros para tarefas triviais.

A filosofia de *Go* vai de encontro ao meu pensamento: quanto menos bibliotecas de terceiros eu usar, melhor. Por segurança, por comodidade, por menos coisas para me preocupar, por querer uma linguagem com o máximo de "baterias inclusas".

Então sempre me deu preguiça construir *APIs* em *Go*, pois o mais fácil é utilizar algum *muxer* não incluso. Isso para mim é uma tarefa básica, portanto a linguagem deveria implementar da melhor maneira. Assim, cá estou eu feliz com as promessas da versão *1.22*.

### Infraestrutura

É preciso ter o compilador na versão correta: *1.22rc1*.

Uso o [asdf](https://asdf-vm.com/) para gerenciar as linguagens de programação que utilizo. Com ele, basta instalar indicando a versão desejada:

```
asdf install golang 1.22rc1
asdf global golang 1.22rc1
asdf reshim golang
```

Lembrando que se não quiser tornar essa versão a utilizada globalmente, basta entrar na pasta que queira restringir a versão e executar o seguinte comando:

```
asdf local golang 1.22rc1
```

A forma normalmente indicada para versões não definitivas, é utilizar o [gotip](https://pkg.go.dev/golang.org/dl/gotip):

```
go install golang.org/dl/gotip@latest
gotip download
```

Se utilizar o *gotip*, em todas as situações em que dever usar o comando *go*, substitua por *gotip*, mantendo os parâmetros.

### Minhas fontes

Comecei lendo o artigo de Eli Bendersky sobre isso:

> https://eli.thegreenplace.net/2023/better-http-server-routing-in-go-122/

E, conforme lá indicado, dei uma olhada na documentação da linguagem:

> https://pkg.go.dev/net/http@go1.22rc1#hdr-Patterns

### O programa

Adaptado das fontes acima, eis:

```
package main

import (
  "fmt"
  "net/http"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("GET /path/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "got path\n")
  })

  mux.HandleFunc("GET /gospel/{version}/{testament}/{book}/{chapter}/", func(w http.ResponseWriter, r *http.Request) {
    version := r.PathValue("version")
    testament := r.PathValue("testament")
    book := r.PathValue("book")
    chapter := r.PathValue("chapter")

    fmt.Fprintf(w, "handling gospel with version=%v, testament=%v, book=%v, chapter=%v\n", version, testament, book, chapter)
  })

  http.ListenAndServe("127.0.0.1:8090", mux)
}
```

Perceba-se que ao utilizar `{book}` na configuração do endpoint, pode-se acessar a variável na posição com `book := r.PathValue("book")`. Além de se poder indicar qual o verbo utilizado (nesse caso `GET`). Caso se queira vários métodos para uma *URL*, basta omitir o verbo.

Para executar, as possibilidades, conforme se instalou a nova versão de *Go*. Pelo asdf, ou instalação direta:

```
go run server.go
```

Ou pelo *gotip*:

```
gotip run server.go
```

Executei o programa tanto em um *Debian*, como em um *Fedora*. No *Fedora* rolou de boas, mas no Debian simplesmenente não foi:

```
$ curl localhost:8090/gospel/almeida/new/marcos/3/
404 page not found
```

E para o outro endpoint:

```
$ curl localhost:8090/path/
404 page not found
```

Lendo os documentos acima indicados com mais atenção, descobri um parâmetro que habilita ou desabilita essa feature. COofigurando uma variável de ambiente no terminal em que o servidor é executado, tudo funciona:

```
$ export GODEBUG=httpmuxgo121=0
$ go run http_server.go
```

Ou então, passando a variável na linha de execução:

```
$ curl localhost:8090/path/
got path
```

E o outro endpoint:

```
$ curl localhost:8090/gospel/almeida/new/marcos/3/
handling gospel with version=almeida, testament=new, book=marcos, chapter=3
```