Gorilla mux необязательные значения запроса

Я работал над проектом Go, где в качестве маршрутизатора используется gorilla / mux.

Мне нужно иметь возможность иметь значения запроса, связанные с маршрутом, но эти значения должны быть необязательными. Это означает, что я хотел бы поймать оба /articles/123 а также /articles/123?key=456 в том же обработчике.

Для достижения этой цели я попытался с помощью r.Queries метод, который принимает пары ключ / значение: маршрутизатор.

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

но это делает только ценность (456) необязательно, но не key, Так что оба /articles/123?key=456 а также /articles/123?key= действительны, но не /articles/123,

Изменить: еще одно требование заключается в том, что после регистрации маршрута, я хотел бы построить их программно, и я не могу понять, как использовать r.Queries хотя в документах конкретно указано, что это возможно ( https://github.com/gorilla/mux).

Ответ @jmaloney работает, но не позволяет создавать URL-адреса из имен.

2 ответа

Решение

Я бы просто зарегистрировал твой обработчик дважды.

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

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

Вот рабочая программа для демонстрации. Обратите внимание, что я использую r.FormValue чтобы получить параметр запроса.

Примечание: убедитесь, что у вас установлена ​​последняя версия go get -u github.com/gorilla/mux так как ошибка параметров запроса не добавлялась, встроенные URL были недавно исправлены.

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()))
}

Если вы регистрируете параметры запроса, они необходимы doc:

Все переменные, определенные в маршруте, являются обязательными, и их значения должны соответствовать соответствующим шаблонам.

Поскольку эти параметры являются необязательными, вам просто нужно проверить их внутри функции-обработчика: id, found := mux.Vars(r)["id"], куда found покажет, если параметр в запросе или нет.

Похоже, что лучший способ обрабатывать необязательные параметры URL-адреса - это определить ваш маршрутизатор как обычно без них, а затем проанализировать необязательные параметры следующим образом:

urlParams := request.URL.Query()

Это возвращает карту, которая содержит параметры URL в виде пар ключ / значение.

Другие вопросы по тегам