web-dev-qa-db-fra.com

Valeurs de requête facultatives Gorilla mux

Je travaille sur un projet Go où gorilla/mux est utilisé comme routeur.

Je dois pouvoir associer des valeurs de requête à une route, mais ces valeurs doivent être facultatives . Cela signifie que j'aimerais attraper à la fois /articles/123 et /articles/123?key=456 dans le même gestionnaire.

Pour ce faire, j'ai essayé d'utiliser la méthode r.Queries qui accepte les paires clé/valeur: Router.

  Path("/articles/{id:[0-9]+}").Queries("key", "{[0-9]*?}")

mais cela rend seulement la valeur (456) facultative, mais pas la key. Donc, /articles/123?key=456 et /articles/123?key= sont valides, mais pas /articles/123.

Edit: une autre condition est que, après avoir enregistré la route, je souhaite les construire par programme, et je n'arrive pas à comprendre comment utiliser r.Queries même si la documentation indique spécifiquement que c'est possible ( https: // github.com/gorilla/mux#registered-urls ).

@jmaloney answer fonctionne, mais ne permet pas de créer des URL à partir de noms.

6
stassinari

Je voudrais juste enregistrer votre gestionnaire deux fois.

router.Path("/articles/{id:[0-9]+}").
    Queries("key", "{[0-9]*?}").
    HandlerFunc(YourHandler).
    Name("YourHandler")

router.Path("/articles/{id:[0-9]+}").HandlerFunc(YourHandler)

Voici un programme de travail à démontrer. Notez que j'utilise r.FormValue pour obtenir le paramètre de requête. 

Remarque: assurez-vous de disposer d'une version à jour go get -u github.com/gorilla/mux car un bogue des paramètres de requête n'ayant pas été ajoutés aux URL construites a été corrigé récemment.

package main

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

    "github.com/gorilla/mux"
)

var router = mux.NewRouter()

func main() {
    router.Path("/articles/{id:[0-9]+}").Queries("key", "{key}").HandlerFunc(YourHandler).Name("YourHandler")
    router.Path("/articles/{id:[0-9]+}").HandlerFunc(YourHandler)

    if err := http.ListenAndServe(":9000", router); err != nil {
        log.Fatal(err)
    }
}

func YourHandler(w http.ResponseWriter, r *http.Request) {
    id := mux.Vars(r)["id"]
    key := r.FormValue("key")

    u, err := router.Get("YourHandler").URL("id", id, "key", key)
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    // Output:
    // /articles/10?key=[key]
    w.Write([]byte(u.String()))
}
13
jmaloney

Si vous enregistrez des paramètres de requête, ils sont obligatoires doc :

Toutes les variables définies dans la route sont obligatoires et leurs valeurs doivent être conformes aux modèles correspondants. 

Ces paramètres étant optionnels, il vous suffit de les vérifier dans une fonction de gestionnaire: id, found := mux.Vars(r)["id"]. Où found montrera si le paramètre dans la requête ou pas.

0
Pavlo Strokov