taironas / route

URL router in Go allowing usage of regexp in URL paths.
Apache License 2.0
2 stars 1 forks source link

Extend route to deal with http.Handle #9

Closed santiaago closed 9 years ago

santiaago commented 9 years ago

I would like to extend route to deal with http.Handle("/", http.FileServer(http.Dir(*root)))

route works well for golang app engine apps as in gonawin main.go because you have a app.yaml file where you can define where the root static files are.

example:

- url: /
  static_files: static/index.html
  upload: static/index.html

This is good when you have an appengine angularjs app where you have the client side working with angularjs routes

example.com/#/route1
example.com/#/route2

And an api that you can use that goes into the app engine backend which could respond with some json for example:

example.com/api/something1
example.com/api/something1

However in a non appengine web app like greentros routes is not as useful. Here is why:

This is the entry point for this golang web app that runs in heroku:

var root = flag.String("root", ".", "file system path")

func main() {
    http.HandleFunc("/api/something1", something1Handler)
    http.HandleFunc("/api/something2", something2Handler)
    http.Handle("/", http.FileServer(http.Dir(*root)))
    log.Println("Listening on 8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

Here is the current main.go

In this case, http.Handle("/", http.FileServer(http.Dir(*root))) is what handles the angularjs app. And http.HandleFunc("/aip/something1", something1Handler)is what could handle json responses.

route can deal with HandleFunc but I cannot use route for HandleFunc and http.Handle("/", http.FileServer(http.Dir(*root)))

santiaago commented 9 years ago

Nice! I will test it and let you know!

santiaago commented 9 years ago

Should we add some documentation about this?

santiaago commented 9 years ago

I tried this in greentros, index.html gets read but other ressources dont:

screen shot 2014-12-26 at 02 44 28

rjourde commented 9 years ago

Serving Satic file with go:

External package solution

Example with Gorilla/Mux

func ServeStatic(router *mux.Router, staticDirectory string) {
    staticPaths := map[string]string{
        "styles":           staticDirectory + "/styles/",
        "bower_components": staticDirectory + "/bower_components/",
        "images":           staticDirectory + "/images/",
        "scripts":          staticDirectory + "/scripts/",
    }
    for pathName, pathValue := range staticPaths {
        pathPrefix := "/" + pathName + "/"
        router.PathPrefix(pathPrefix).Handler(http.StripPrefix(pathPrefix,
            http.FileServer(http.Dir(pathValue))))
    }
}
router := mux.NewRouter()
staticDirectory := "/static/"
ServeStatic(router, staticDirectory)

Notice that using router.PathPrefix will solve the recursive issue above so for example you would be able to load your scripts by using /static/some/path/to/script.js

source: http://www.shakedos.com/2014/Feb/08/serving-static-files-with-go.html

santiaago commented 9 years ago

maybe I am wrong but if I have to do all that I do not see the benefit of using route, since a http.Handle("/", http.FileServer(http.Dir(*root))) is enough.

santiaago commented 9 years ago

I found a solution, I am going to try this out and let you know.

santiaago commented 9 years ago

With commit 4da5b74a461d96825847ecc85f9a1ef28e734d9b

you can now have the following app with no 404 on static ressources of backend routes.

Let me know if this is ok , and feel free to merge.

package main

import (
    "flag"
    "github.com/taironas/route"
    "log"
    "net/http"
    "os"
)

var root = flag.String("root", "app", "file system path")

func main() {
    r := new(route.Router)

    r.HandleFunc("/black/?", blackHandler)
    r.HandleFunc("/green/?", greenHandler)
    r.HandleFunc("/blue/?", blueHandler)
    r.HandleFunc("/red/?", redHandler)

    r.AddStaticRoute(root)

    log.Println("Listening on " + os.Getenv("PORT"))
    err := http.ListenAndServe(":"+os.Getenv("PORT"), r)
    if err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}
rjourde commented 9 years ago

Nice! That looks fine to me. I just have one comment. Shouldn't we name that "staticResources" instead of "staticRoutes" and "AddStaticResources" instead of "AddStaticRoute" ?

I will merge into dev branch, and I will update the test and the doc.

santiaago commented 9 years ago

Cool! I don't mind changing the name :+1: