Created
December 5, 2014 12:03
Revisions
-
nmerouze created this gist
Dec 5, 2014 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,117 @@ package main import ( "encoding/json" "log" "net/http" "reflect" "time" "github.com/gorilla/context" "github.com/julienschmidt/httprouter" "github.com/justinas/alice" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) // Repo type Tea struct { Id bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"` Name string `json:"name"` Category string `json:"category"` } type TeaResource struct { Data Tea `json:"data"` } type TeaRepo struct { coll *mgo.Collection } func (r *TeaRepo) Find(id string) (TeaResource, error) { result := TeaResource{} err := r.coll.FindId(bson.ObjectIdHex(id)).One(&result.Data) if err != nil { return result, err } return result, nil } type appContext struct { db *mgo.Database } func (c *appContext) teaHandler(w http.ResponseWriter, r *http.Request) { params := context.Get(r, "params").(httprouter.Params) repo := TeaRepo{c.db.C("teas")} tea, err := repo.Find(params.ByName("id")) if err != nil { panic(err) } w.Header().Set("Content-Type", "application/vnd.api+json") json.NewEncoder(w).Encode(tea) } func recoverHandler(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { log.Printf("panic: %+v", err) http.Error(w, http.StatusText(500), 500) } }() next.ServeHTTP(w, r) } return http.HandlerFunc(fn) } func loggingHandler(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { t1 := time.Now() next.ServeHTTP(w, r) t2 := time.Now() log.Printf("[%s] %q %v\n", r.Method, r.URL.String(), t2.Sub(t1)) } return http.HandlerFunc(fn) } type router struct { *httprouter.Router } func (r *router) Get(path string, handler http.Handler) { r.GET(path, wrapHandler(handler)) } func NewRouter() *router { return &router{httprouter.New()} } func wrapHandler(h http.Handler) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { context.Set(r, "params", ps) h.ServeHTTP(w, r) } } func main() { session, err := mgo.Dial("localhost") if err != nil { panic(err) } defer session.Close() session.SetMode(mgo.Monotonic, true) appC := appContext{session.DB("test")} commonHandlers := alice.New(context.ClearHandler, loggingHandler, recoverHandler) router := NewRouter() router.Get("/teas/:id", commonHandlers.ThenFunc(appC.teaHandler)) http.ListenAndServe(":8080", router) }