запросы gorilla / mux не соответствуют шаблону URL

Я просматриваю старый код простого веб-сервера, который я написал некоторое время назад, и мои шаблоны запросов больше не работают. У меня есть функция, которая инициализирует мои маршруты следующим образом:

func (a *App) InitializeRoutes() {
    a.Router.HandleFunc("/api/forecast/detailed?city={city}&state={state}&period={period}", a.DetailedForecast).Methods("GET")
    a.Router.HandleFunc("/api/forecast/detailed?city={city}&state={state}", a.DetailedForecast).Methods("GET")
    a.Router.HandleFunc("/api/forecast/detailed?random", a.RandomDetailedForecast).Methods("GET")
    a.Router.HandleFunc("/api/forecast/hourly?city={city}&state={state}&hours={hours}", a.HourlyForecast).Methods("GET")
    a.Router.HandleFunc("/api/forecast/hourly?city={city}&state={state}", a.HourlyForecast).Methods("GET")
    a.Router.NotFoundHandler = http.HandlerFunc(a.Custom404Handler)
}

Мой собственный обработчик 404 просто возвращает json {"error": "Not Found"}

Отсюда я инициализирую эти маршруты в конце функции инициализации моего приложения (нижние 3 строки):

func (a *App) Initialize() {
    var err error
    conf.configure()
    sqlDataSource := fmt.Sprintf(
        "postgres://%s:%s@%s:%s/%s?sslmode=disable",
        conf.sqlUsername,
        conf.sqlPassword,
        conf.sqlHost,
        conf.sqlPort,
        conf.sqlDbName)
    a.DB, err = sql.Open("postgres", sqlDataSource)
    if err != nil {
        log.Fatal(err)
    }
    a.Redis = redis.NewClient(&redis.Options{
        Addr:     fmt.Sprintf("%s:%s", conf.redisHost, conf.redisPort),
        Password: conf.redisPassword,
        DB:       conf.redisDb,
    })
    a.Router = mux.NewRouter()
    a.Logger = handlers.CombinedLoggingHandler(os.Stdout, a.Router)
    a.InitializeRoutes()
}

Мое приложение работает со следующей функцией:

func (a *App) Run() {
    port := fmt.Sprintf(":%s", os.Getenv("SERVER_PORT"))
    log.Fatal(http.ListenAndServe(port, a.Logger))
}

И мой сервер работает:

func main() {
    a := App{}
    a.Initialize()
    a.Run()
}

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

>>> import requests
>>> r = requests.get("http://localhost:8000/api/forecast/detailed?city=Chicago&state=IL")
>>> r
<Response [404]>
>>> r.json()
{'error': 'Not Found'}

ИЗМЕНИТЬ

Я внес изменения, чтобы переместить запрос из URL-адреса. Мои маршруты теперь выглядят так:

a.Router.HandleFunc("/api/forecast/detailed", a.DetailedForecast).Queries("city", "{city:[a-zA-Z+]+}", "state", "{state:[a-zA-Z+]+}", "period", "{period:[a-zA-Z+]+}").Schemes("http").Methods("GET")
a.Router.HandleFunc("/api/forecast/detailed", a.DetailedForecast).Queries("city", "{city:[a-zA-Z+]+}", "state", "{state:[a-zA-Z+]+}").Schemes("http").Methods("GET")
a.Router.HandleFunc("/api/forecast/detailed/random", a.RandomDetailedForecast).Schemes("http").Methods("GET")
a.Router.HandleFunc("/api/forecast/hourly", a.HourlyForecast).Queries("city", "{city:[a-zA-Z+]+}", "state", "{state:[a-zA-Z+]+}", "hours", "{hours:[0-9]+}").Schemes("http").Methods("GET")
a.Router.HandleFunc("/api/forecast/hourly", a.HourlyForecast).Queries("city", "{city:[a-zA-Z+]+}", "state", "{state:[a-zA-Z+]+}").Schemes("http").Methods("GET")

Когда я делаю такой же запрос, я вижу:

Get : unsupported protocol scheme ""

Я проверил URL-адрес, чтобы увидеть, что отправляется:

2020/02/20 18:19:41 Scheme is:
2020/02/20 18:19:41 Host is:
2020/02/20 18:19:41 Path is: /api/forecast/detailed
2020/02/20 18:19:41 Query is: city=Chicago&state=IL

Путь и запрос выглядят правильно, но я не понимаю, почему схема недействительна. Мой запрос все еще r = requests.get("http://localhost:8000/api/forecast/detailed?city=Chicago&state=IL")


person K Pekosh    schedule 20.02.2020    source источник
comment
HandleFunc принимает только путь, без параметров запроса и т. д. Для параметров запроса используйте Route.Queries.   -  person mkopriva    schedule 20.02.2020
comment
@mkopriva это недавнее изменение гориллы? Кажется, я не припомню, чтобы раньше у меня была такая проблема.   -  person K Pekosh    schedule 20.02.2020
comment
Я никогда не использовал gorilla / mux, поэтому не знаю. Если вам все равно, вы можете перейти на их страницу на github и просмотреть коммиты.   -  person mkopriva    schedule 20.02.2020


Ответы (1)


Из README ... Для сопоставления запросов необходимо использовать

r := mux.NewRouter()
...
r.Queries("key", "value")

Чтобы соответствовать PathPrefix

r.PathPrefix("/products/")

Я думаю, вам нужно объединить эти два, чтобы достичь того, чего вы хотите.

person Lucas Katayama    schedule 20.02.2020