httpgohttprouter

Serve static content on root and rest on /api


I'm using httprouter for parsing some parameters from the path in api calls:

router := httprouter.New()
router.GET("/api/:param1/:param2", apiHandler)

And wanted to add some files to the root (/) to serve. It's just index.html, script.js and style.css. All in a local directory called static

router.ServeFiles("/*filepath", http.Dir("static"))

So that I can go with the browser to localhost:8080/ and it will serve index.html and the js from the browser will call the /api/:param1/:param2

But this path conflicts with the /api path.

panic: wildcard route '*filepath' conflicts with existing children in path '/*filepath'


Solution

  • As others pointed out, this is not possible using only github.com/julienschmidt/httprouter.

    Note that this is possible using the multiplexer of the standard library, as detailed in this answer: How do I serve both web pages and API Routes by using same port address and different Handle pattern

    If you must serve all your web content at the root, another viable solution could be to mix the standard router and julienschmidt/httprouter. Use the standard router to register and serve your files at the root, and use julienschmidt/httprouter to serve your API requests.

    This is how it could look like:

    router := httprouter.New()
    router.GET("/api/:param1/:param2", apiHandler)
    
    mux := http.NewServeMux()
    mux.Handle("/", http.FileServer(http.Dir("static")))
    mux.Handle("/api/", router)
    
    log.Fatal(http.ListenAndServe(":8080", mux))
    

    In the example above, all requests that start with /api/ will be forwarded to the router handler, and the rest will be attempted to handle by the file server.