I'm visiting some old code for a simple webserver I wrote some time ago, and my request patterns are no longer working. I have a function that initializes my routes as follows:
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)
}
My custom 404 handler just returns a json of {"error": "Not Found"}
From here, I initialize these routes at the end of my app's initialize function (bottom 3 lines):
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()
}
My app runs on the following function:
func (a *App) Run() {
port := fmt.Sprintf(":%s", os.Getenv("SERVER_PORT"))
log.Fatal(http.ListenAndServe(port, a.Logger))
}
And my server runs on:
func main() {
a := App{}
a.Initialize()
a.Run()
}
When I try and make a request to what as far as I can tell is a valid URL pattern, I get the following:
>>> import requests
>>> r = requests.get("http://localhost:8000/api/forecast/detailed?city=Chicago&state=IL")
>>> r
<Response [404]>
>>> r.json()
{'error': 'Not Found'}
EDIT
I made the change to move the query out of the URL. My routes now look like this:
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")
When I make the same request, I am now seeing:
Get : unsupported protocol scheme ""
I've inspected the URL to see what is being sent:
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
The path and the query look correct, but I do not understand why the scheme is invalid. My request is still r = requests.get("http://localhost:8000/api/forecast/detailed?city=Chicago&state=IL")
HandleFunc
takes a path only, no query params etc. For query params useRoute.Queries
. – mkopriva