I have simple web application with CRUD operation, I want to serve web pages and API routes using same port address and different Handle pattern. As follows,
fs := http.FileServer(http.Dir("server/webapps/play_maths"))
http.Handle("/", fs)
http.Handle("/api", call API routes)
Following is my API routes
func UserRoutes() *mux.Router {
var router = mux.NewRouter()
router = mux.NewRouter().StrictSlash(true)
router.HandleFunc("/user/create", api.CreateUser)
router.HandleFunc("/user/get/all", api.GetAllUsers)
return router
}
This is supported by the net/http
package out-of-the-box. Quoting from http.ServeMux
:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
So simply you can register your file handler to path /
, and register an API handler to e.g. /api/
path. In this scenario any requests that start with /api/
will be directed to the API handler, and any other requests will be directed to the file handler.
Note that this of course means if there are files that are in the /api/
folder (or more specifically whose request paths start with /api/
), they won't be reachable for the above mentioned reason.
I did following changers to my code and now it's running as I expected.
func main() {
//Starting the API server
router := routes.UserRoutes()
http.Handle("/api/", router)
//Starting the FileServer
fs := http.FileServer(http.Dir("server/webapps/play_maths"))
http.Handle("/", fs)
log.Println("Listening...")
log.Fatal(http.ListenAndServe(":3000", nil))
}
Then I change my routes as follows.
func UserRoutes() *mux.Router {
var router = mux.NewRouter()
router = mux.NewRouter().StrictSlash(true)
router.HandleFunc("/api/user/create", api.CreateUser)
router.HandleFunc("/api/user/get/all", api.GetAllUsers)
return router
}