91 votes

Comment puis-je gérer les requêtes http de différentes méthodes vers / en Go ?

Je cherche à trouver la meilleure façon de gérer les demandes vers / et seulement / en Go et de gérer différentes méthodes de différentes manières. Voici ce que j'ai trouvé de mieux :

package main

import (
    "fmt"
    "html"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path != "/" {
            http.NotFound(w, r)
            return
        }

        if r.Method == "GET" {
            fmt.Fprintf(w, "GET, %q", html.EscapeString(r.URL.Path))
        } else if r.Method == "POST" {
            fmt.Fprintf(w, "POST, %q", html.EscapeString(r.URL.Path))
        } else {
            http.Error(w, "Méthode de requête invalide.", 405)
        }
    })

    log.Fatal(http.ListenAndServe(":8080", nil))
}

Est-ce idiomatique en Go ? Est-ce le mieux que je puisse faire avec la librairie http standard ? Je préférerais vraiment faire quelque chose comme http.HandleGet("/", handler) comme dans express ou Sinatra. Y a-t-il un bon framework pour écrire des services REST simples ? web.go semble attrayant mais semble stagnant.

Merci pour vos conseils.

118voto

andybalholm Points 3197

Pour vous assurer que vous ne servez que la racine : Vous faites la bonne chose. Dans certains cas, vous voudriez appeler la méthode ServeHttp d'un objet http.FileServer au lieu d'appeler NotFound; cela dépend si vous avez des fichiers divers que vous souhaitez également servir.

Pour gérer différemment différentes méthodes : Beaucoup de mes gestionnaires HTTP ne contiennent rien d'autre qu'un énoncé switch comme celui-ci :

switch r.Method {
case http.MethodGet:
    // Servir la ressource.
case http.MethodPost:
    // Créer un nouvel enregistrement.
case http.MethodPut:
    // Mettre à jour un enregistrement existant.
case http.MethodDelete:
    // Supprimer l'enregistrement.
default:
    http.Error(w, "Méthode non autorisée", http.StatusMethodNotAllowed)
}

Biensûr, vous pouvez trouver qu'un package tiers comme gorilla fonctionne mieux pour vous.

43voto

dskinner Points 2692

Eh, je m'apprêtais en fait à aller me coucher et donc le bref commentaire sur le fait de regarder http://www.gorillatoolkit.org/pkg/mux qui est vraiment sympa et fait ce que vous voulez, il suffit de jeter un coup d'œil à la documentation. Par exemple

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/products", ProductsHandler)
    r.HandleFunc("/articles", ArticlesHandler)
    http.Handle("/", r)
}

et

r.HandleFunc("/products", ProductsHandler).
    Host("www.domaine.com").
    Methods("GET").
    Schemes("http")

et de nombreuses autres possibilités et façons d'effectuer les opérations ci-dessus.

Mais j'ai ressenti le besoin de répondre à l'autre partie de la question, "Est-ce la meilleure chose que je puisse faire". Si la bibliothèque standard est un peu trop limitée, une excellente ressource à consulter est ici: https://github.com/golang/go/wiki/Projects#web-libraries (lien spécifique aux bibliothèques web).

3voto

Luc Drenth Points 48

À partir de Go 1.22.0, vous pouvez mettre la méthode HTTP avant le point de terminaison

package main

import (
    "net/http"
)

func main() {
    router := http.NewServeMux()
    router.HandleFunc("GET /", myHandler)
    http.ListenAndServe(":8080", router)
}

https://go.dev/blog/routing-enhancements

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X