コード例 #1
0
ファイル: goji.go プロジェクト: marswang/nosurf
func main() {
	goji.Get("/", IndexHandler) // Doesn't need CSRF protection (no POST/PUT/DELETE actions).

	signup := web.New()
	goji.Handle("/signup/*", signup)
	// But our signup forms do, so we add nosurf to their middleware stack (only).
	signup.Use(nosurf.NewPure)
	signup.Get("/signup/new", ShowSignupForm)
	signup.Post("/signup/submit", SubmitSignupForm)

	admin := web.New()
	// A more advanced example: we enforce secure cookies (HTTPS only),
	// set a domain and keep the expiry time low.
	a := nosurf.New(admin)
	a.SetBaseCookie(http.Cookie{
		Name:     "csrf_token",
		Domain:   "localhost",
		Path:     "/admin",
		MaxAge:   3600 * 4,
		HttpOnly: true,
		Secure:   true,
	})

	// Our /admin/* routes now have CSRF protection.
	goji.Handle("/admin/*", a)

	goji.Serve()
}
コード例 #2
0
func static() {
	g.Get("/", http.FileServer(http.Dir(config.C.PublicPath)))

	static := web.New()
	static.Get("/styles/*", http.StripPrefix("/styles/", http.FileServer(http.Dir(config.C.PublicPath+"/styles"))))
	static.Get("/scripts/*", http.StripPrefix("/scripts/", http.FileServer(http.Dir(config.C.PublicPath+"/scripts"))))
	static.Get("/images/*", http.FileServer(http.Dir(config.C.PublicPath+"/images")))
	static.Get("/robots.txt", http.FileServer(http.Dir(config.C.PublicPath)))

	g.Handle("/scripts/*", static)
	g.Handle("/styles/*", static)
	g.Handle("/images/*", static)
}
コード例 #3
0
ファイル: main.go プロジェクト: myohei/sample-goji-server
func main() {
	admin := web.New()
	admin.Use(middleware.SubRouter)
	admin.Post("/login", login)
	goji.Handle("/admin/*", admin)

	dashboard := web.New()
	dashboard.Use(auth)
	dashboard.Use(middleware.SubRouter)
	dashboard.Get("/json", sampleJsonHandle)
	goji.Handle("/dashboard/*", dashboard)

	goji.Use(middleware.Logger)
	goji.Serve()
}
コード例 #4
0
ファイル: main.go プロジェクト: cognusion/post2s3
func main() {

	// Handle debugging
	if debug || os.Getenv("DEBUG") == "true" {
		debug = true // Just in case
		debugOut = log.New(os.Stdout, "[DEBUG]", log.Lshortfile)
	}

	debugOut.Printf("Pre-Config:\n%+v\n", GlobalConfig.Map())

	// Load Configs
	if configFolder != "" {
		loadConfigs(configFolder)
	} else if cf := os.Getenv("CONFIGFOLDER"); cf != "" {
		loadConfigs(cf)
	}

	debugOut.Printf("Post-Config\n%+v\n", GlobalConfig.Map())

	// Setup AWS stuff
	initAWS()

	// Goji!!!
	if GlobalConfig.IsNotNull("serverHeader") {
		headerString := GlobalConfig.Get("serverHeader")
		if headerString != "yes" {
			FULLVERSION = headerString
		}
		goji.Use(ServerHeader)
	}

	goji.Get("/", http.RedirectHandler(GlobalConfig.Get("formURL"), 301))
	goji.Get("/health", healthHandler)
	goji.Post("/upload", uploadHandler)
	goji.Get("/upload", http.RedirectHandler(GlobalConfig.Get("getRedirect"), 301))

	// Allow handling of static content for webform, thank you page, etc.
	if GlobalConfig.IsNotNull("staticPath") && GlobalConfig.IsNotNull("staticURL") {
		debugOut.Printf("Static handling of '%s' mapped to '%s'\n", GlobalConfig.Get("staticURL"), GlobalConfig.Get("staticPath"))
		goji.Handle(GlobalConfig.Get("staticURL"),
			http.StripPrefix(strings.TrimRight(GlobalConfig.Get("staticURL"), "*"),
				http.FileServer(http.Dir(GlobalConfig.Get("staticPath")))))
	}

	goji.Handle("/*", defaultHandler)

	goji.Serve()
}
コード例 #5
0
ファイル: main.go プロジェクト: tkzwtks/go_blog
func main() {
	// setup
	models.Migrate()
	pongo2.DefaultSet.SetBaseDirectory("view")

	api := web.New()
	goji.Handle("/api/*", api)
	api.Use(middleware.SubRouter)
	api.Get("/entry/:id", controller.ShowArticle)
	api.Get("/album/:id", controller.ShowAlbum)

	goji.Handle("/", http.FileServer(http.Dir("./static")))
	goji.Handle(regexp.MustCompile("^/(css|js)"), http.FileServer(http.Dir("./static")))

	goji.Serve()
}
コード例 #6
0
func NewRouter(b *backend.Backend) {
	router = Router{
		Backend: b,
	}

	goji.Get("/ping", router.Ping)
	api := web.New()
	goji.Handle("/v1/*", api)

	api.Get("/overview", router.Overview)

	api.Get("/accounts", router.ShowAccount)
	api.Get("/accounts/:account_id", router.ShowAccount)
	api.Get("/categories", router.ShowCategory)
	api.Get("/categories/:category_id", router.ShowCategory)

	api.Post("/transaction", router.NewTransaction)
	api.Post("/account", router.NewAccount)
	api.Post("/category", router.NewCategory)

	api.Put("/transaction/:transaction_id", router.UpdateTransaction)
	api.Put("/account/:account_id", router.UpdateAccount)
	api.Put("/category/:category_id", router.UpdateCategory)

	api.Delete("/transaction/:transaction_id", router.DeleteTransaction)
	api.Delete("/account/:account_id", router.DeleteAccount)
	api.Delete("/category/:category_id", router.DeleteCategory)

	api.Use(goji.DefaultMux.Router)
	api.Use(middleware.SubRouter)
}
コード例 #7
0
func main() {
	goji.Get("/hello/:name", hello)

	staticPattern := regexp.MustCompile("^/(css|js)")
	goji.Handle(staticPattern, http.FileServer(http.Dir("./static")))
	goji.Serve()
}
コード例 #8
0
ファイル: webserver.go プロジェクト: topscore/sup
func StartWebServer(bind, auth string) error {
	err := loadTemplates()
	if err != nil {
		return err
	}

	if auth != "" {
		authParts := strings.Split(auth, ":")
		goji.Use(httpauth.SimpleBasicAuth(authParts[0], authParts[1]))
	}

	goji.Get("/", homeRoute)
	goji.Get("/status", statusRoute)
	goji.Get("/robots.txt", robotsRoute)
	goji.Get("/setEnabled", setEnabledRoute)
	goji.Handle("/config", configRoute)

	listener, err := net.Listen("tcp", bind)
	if err != nil {
		return err
	}

	goji.ServeListener(listener)
	return nil
}
コード例 #9
0
ファイル: shortlink.go プロジェクト: crewjam/dynamotree
func main() {
	awsSession := session.New()
	awsSession.Config.WithRegion(os.Getenv("AWS_REGION"))

	tree = &dynamotree.Tree{
		TableName: "hstore-example-shortlinks",
		DB:        dynamodb.New(awsSession),
	}
	err := tree.CreateTable()
	if err != nil {
		log.Fatalf("hstore: %s", err)
	}

	goji.Get("/:link", ServeLink)
	goji.Post("/signup", CreateAccount)

	authMux := web.New()
	authMux.Use(RequireAccount)
	authMux.Post("/", CreateLink)
	authMux.Get("/", ListLinks)
	authMux.Delete("/:link", DeleteLink) // TODO(ross): this doesn't work (!)
	goji.Handle("/", authMux)

	goji.Serve()
}
コード例 #10
0
ファイル: cgradmin.go プロジェクト: MartinChenjq/cgradmin
func Start(conn *CGRConnector, user, pass string) {
	connector = conn
	username = user
	password = pass
	templates = template.Must(template.ParseGlob("templates/*.tmpl"))

	rpc.Register(conn)

	goji.Get(LOGIN_PATH, loginGet)
	goji.Post(LOGIN_PATH, loginPost)

	goji.Get("/app/*", http.FileServer(http.Dir("./static")))

	auth := web.New()
	goji.Handle("/*", auth)
	auth.Use(SessionAuth)
	auth.Handle("/ws", websocket.Handler(func(ws *websocket.Conn) {
		jsonrpc.ServeConn(ws)
	}))
	auth.Post("/import/", importPost)
	auth.Post("/exportcdrs/", exportCdrsPost)
	auth.Post("/exporttpcsv/", exportTpToCsvPost)
	auth.Get("/accounts/logout", logoutGet)
	auth.Get("/", http.RedirectHandler("/app/", 301))
}
コード例 #11
0
ファイル: urls.go プロジェクト: shonenada-archives/heron
func SetupRoutes() {
	for _, route := range routes {
		for _, method := range route.methods {
			switch method {
			case "GET":
				goji.Get(route.url, route.handler)
				break
			case "POST":
				goji.Post(route.url, route.handler)
				break
			case "PUT":
				goji.Put(route.url, route.handler)
				break
			case "PATCH":
				goji.Patch(route.url, route.handler)
				break
			case "DELETE":
				goji.Delete(route.url, route.handler)
				break
			default:
				goji.Handle(route.url, route.handler)
			}
		}
	}
}
コード例 #12
0
ファイル: web.go プロジェクト: cubeee/go-sig
func main() {
	log.Println("Starting go-sig/web")

	if path := os.Getenv("IMG_PATH"); path != "" {
		imageRoot = path
	}
	log.Printf("Using image root: %s", imageRoot)
	if _, err := os.Stat(imageRoot); os.IsNotExist(err) {
		os.MkdirAll(imageRoot, 0750)
	}

	if procs := os.Getenv("PROCS"); procs != "" {
		if p, err := strconv.Atoi(procs); err != nil {
			runtime.GOMAXPROCS(p)
		}
	}

	if key := os.Getenv("AES_KEY"); key != "" {
		util.AES_KEY = []byte(key)
	}

	disableLogging := os.Getenv("DISABLE_LOGGING")
	if disableLogging == "1" || disableLogging == "true" {
		log.SetOutput(new(NullWriter))
	}

	// Routes
	log.Println("Mapping routes...")
	goji.Get("/", index)

	// Setup static files
	static := web.New()
	static.Get("/assets/*", http.StripPrefix("/assets/", http.FileServer(http.Dir(publicPath))))
	http.Handle("/assets/", static)

	profile := os.Getenv("ENABLE_DEBUG")
	if profile == "1" || profile == "true" {
		log.Println("Mapping debug routes...")
		goji.Handle("/debug/pprof/", pprof.Index)
		goji.Handle("/debug/pprof/cmdline", pprof.Cmdline)
		goji.Handle("/debug/pprof/profile", pprof.Profile)
		goji.Handle("/debug/pprof/symbol", pprof.Symbol)
		goji.Handle("/debug/pprof/block", pprof.Handler("block").ServeHTTP)
		goji.Handle("/debug/pprof/heap", pprof.Handler("heap").ServeHTTP)
		goji.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine").ServeHTTP)
		goji.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate").ServeHTTP)
	}

	// Generators
	log.Println("Registering generators...")
	registerGenerator(new(rs3.BoxGoalGenerator))
	registerGenerator(new(multi.MultiGoalGenerator))
	//registerGenerator(new(rs3.ExampleGenerator))

	// Serve
	goji.Serve()
}
コード例 #13
0
ファイル: tweetmodule.go プロジェクト: jchannon/FarGo
//New intialises tweet routes
func New() {
	fmt.Println("Setup Tweets")
	tweets := web.New()
	goji.Handle("/tweets/*", tweets)

	tweets.Use(middleware.SubRouter)
	tweets.Use(conneg)

	tweets.Get("/", helloTweet)
	tweets.Get("/:id", getTweetByID)

}
コード例 #14
0
func main() {
	godotenv.Load()

	access := Access{api.New(os.Getenv("DATABASE_URL"))}
	defer access.Close()

	goji.Post("/post", access.log)

	goji.Handle("/*", http.FileServer(http.Dir("./static")))

	goji.Serve()
}
コード例 #15
0
ファイル: main.go プロジェクト: FihlaTV/bridge-server
func main() {
	// Add routes to the global handler
	goji.Get("/", Root)
	// Fully backwards compatible with net/http's Handlers
	goji.Get("/greets", http.RedirectHandler("/", 301))
	// Use your favorite HTTP verbs
	goji.Post("/greets", NewGreet)
	// Use Sinatra-style patterns in your URLs
	goji.Get("/users/:name", GetUser)
	// Goji also supports regular expressions with named capture groups.
	goji.Get(regexp.MustCompile(`^/greets/(?P<id>\d+)$`), GetGreet)

	// Middleware can be used to inject behavior into your app. The
	// middleware for this application are defined in middleware.go, but you
	// can put them wherever you like.
	goji.Use(PlainText)

	// If the patterns ends with "/*", the path is treated as a prefix, and
	// can be used to implement sub-routes.
	admin := web.New()
	goji.Handle("/admin/*", admin)

	// The standard SubRouter middleware helps make writing sub-routers
	// easy. Ordinarily, Goji does not manipulate the request's URL.Path,
	// meaning you'd have to repeat "/admin/" in each of the following
	// routes. This middleware allows you to cut down on the repetition by
	// eliminating the shared, already-matched prefix.
	admin.Use(middleware.SubRouter)
	// You can also easily attach extra middleware to sub-routers that are
	// not present on the parent router. This one, for instance, presents a
	// password prompt to users of the admin endpoints.
	admin.Use(SuperSecure)

	admin.Get("/", AdminRoot)
	admin.Get("/finances", AdminFinances)

	// Goji's routing, like Sinatra's, is exact: no effort is made to
	// normalize trailing slashes.
	goji.Get("/admin", http.RedirectHandler("/admin/", 301))

	// Use a custom 404 handler
	goji.NotFound(NotFound)

	// Sometimes requests take a long time.
	goji.Get("/waitforit", WaitForIt)

	// Call Serve() at the bottom of your main() function, and it'll take
	// care of everything else for you, including binding to a socket (with
	// automatic support for systemd and Einhorn) and supporting graceful
	// shutdown on SIGINT. Serve() is appropriate for both development and
	// production.
	goji.Serve()
}
コード例 #16
0
ファイル: route.go プロジェクト: woremacx/go-crud-sample
func router(m *web.Mux) http.Handler {
	m.Get("/", UserRoot)
	user := web.New()
	goji.Handle("/user/*", user)
	user.Use(middleware.SubRouter)
	user.Get("/", UserIndex)
	user.Get("/new", UserNew)
	user.Post("/new", UserCreate)
	user.Get("/edit/:id", UserEdit)
	user.Post("/update/:id", UserUpdate)
	user.Get("/delete/:id", UserDelete)
	return m
}
コード例 #17
0
ファイル: route.go プロジェクト: sheercat/go-crud-sample
func main() {
	user := web.New()
	goji.Handle("/user/*", user)

	user.Use(middleware.SubRouter)
	user.Get("/index", UserIndex)
	user.Get("/new", UserNew)
	user.Post("/new", UserCreate)
	user.Get("/edit/:id", UserEdit)
	user.Post("/update/:id", UserUpdate)
	user.Get("/delete/:id", UserDelete)
	goji.Serve()
}
コード例 #18
0
ファイル: router_mold.go プロジェクト: winespace/goji-mold
func (rm *RouterMold) Generate() *web.Mux {
	var mux *web.Mux
	if rm.SubRoutes == "" {
		mux = goji.DefaultMux
		mux.Abandon(middleware.Logger)
	} else {
		mux := web.New()
		mux.Use(middleware.RequestID)
		mux.Use(middleware.Recoverer)
		mux.Use(middleware.AutomaticOptions)
		goji.Handle(rm.SubRoutes, mux)
	}

	for _, m := range rm.Middlewares {
		mux.Use(m.MiddlewareFunc())
	}

	var handlerFunc func(Route) interface{}
	if rm.HandlerFunc == nil {
		handlerFunc = func(r Route) interface{} {
			return r.Handler
		}
	} else {
		handlerFunc = rm.HandlerFunc
	}

	for _, r := range rm.Routes {
		var pattern interface{}
		if r.RegExp != "" {
			pattern = regexp.MustCompile(r.RegExp)
		} else {
			pattern = r.Path
		}
		switch r.Method {
		case "HEAD":
			mux.Head(pattern, handlerFunc(r))
		case "GET":
			mux.Get(pattern, handlerFunc(r))
		case "POST":
			mux.Post(pattern, handlerFunc(r))
		case "PUT":
			mux.Put(pattern, handlerFunc(r))
		case "PATCH":
			mux.Patch(pattern, handlerFunc(r))
		case "DELETE":
			mux.Delete(pattern, handlerFunc(r))
		}
	}

	return mux
}
コード例 #19
0
ファイル: main.go プロジェクト: falzm/httpdump
func main() {
	if flagHelp {
		printUsage(os.Stdout)
		os.Exit(0)
	} else if flagVersion {
		printVersion(version, buildDate)
		os.Exit(0)
	}

	goji.Handle("/*", dump)
	goji.Serve()

	os.Exit(0)
}
コード例 #20
0
ファイル: gossip.go プロジェクト: parkr/gossip
func main() {
	goji.Get("/", handler.SayHello)

	messages := web.New()
	messages.Use(TokenAuthHandler)

	pattern := regexp.MustCompile(`^(?P<id>[0-9]+)$`)
	messages.Get(pattern, handler.FindMessageById)
	messages.Get("/latest", handler.FetchLatestMessages)
	messages.Post("/log", handler.StoreMessage)

	goji.Handle("/api/messages/*", messages)

	serve()
}
コード例 #21
0
func api() {
	api := web.New()
	api.Use(middlewares.Secure)
	api.Use(middlewares.JSON)
	api.Get("/api/tasks", listTasks)
	api.Get("/api/tasks/:id", getTask)
	api.Post("/api/tasks", createTask)

	// If last character is an asterisk,
	// the path is treated as a prefix
	// and can be used to implement
	// sub-routes which can have custom
	// middlewares.
	g.Handle("/api/*", api)
}
コード例 #22
0
func MakeHealthRouter(hcHandler *HealthCheckHandler) http.Handler {

	health := web.New()

	goji.Handle("/health", health)

	health.Use(middleware.EnvInit)
	health.Use(middleware.RequestID)
	health.Use(middleware.RealIP)
	health.Use(middleware.Logger)
	health.Use(context.ClearHandler)

	health.Get("/health", hcHandler.HealthCheck)

	return health
}
コード例 #23
0
ファイル: main.go プロジェクト: hardscoregames/goji
func main() {
	// Add routes to the global handler
	goji.Get("/", Root)
	// Fully backwards compatible with net/http's Handlers
	goji.Get("/greets", http.RedirectHandler("/", 301))
	// Use your favorite HTTP verbs
	goji.Post("/greets", NewGreet)
	// Use Sinatra-style patterns in your URLs
	goji.Get("/users/:name", GetUser)
	// Goji also supports regular expressions with named capture groups.
	goji.Get(regexp.MustCompile(`^/greets/(?P<id>\d+)$`), GetGreet)

	// Middleware can be used to inject behavior into your app. The
	// middleware for this application are defined in middleware.go, but you
	// can put them wherever you like.
	goji.Use(PlainText)

	// If the last character of a pattern is an asterisk, the path is
	// treated as a prefix, and can be used to implement sub-routes.
	// Sub-routes can be used to set custom middleware on sub-applications.
	// Goji's interfaces are completely composable.
	admin := web.New()
	goji.Handle("/admin/*", admin)
	admin.Use(SuperSecure)

	// Goji's routing, like Sinatra's, is exact: no effort is made to
	// normalize trailing slashes.
	goji.Get("/admin", http.RedirectHandler("/admin/", 301))

	// Set up admin routes. Note that sub-routes do *not* mutate the path in
	// any way, so we need to supply full ("/admin/" prefixed) paths.
	admin.Get("/admin/", AdminRoot)
	admin.Get("/admin/finances", AdminFinances)

	// Use a custom 404 handler
	goji.NotFound(NotFound)

	// Sometimes requests take a long time.
	goji.Get("/waitforit", WaitForIt)

	// Call Serve() at the bottom of your main() function, and it'll take
	// care of everything else for you, including binding to a socket (with
	// automatic support for systemd and Einhorn) and supporting graceful
	// shutdown on SIGINT. Serve() is appropriate for both development and
	// production.
	goji.Serve()
}
コード例 #24
0
func getRoute(prefix string, routeConf map[string]func(web.C, http.ResponseWriter, *http.Request)) *web.Mux {
	w := web.New()
	url := prefix + "/"

	// ROUTE TOP
	fmt.Println("[ROUTE]", url)
	for k, v := range routeConf {
		w.Get(url+k, v)
		// ROUTE PRINT
		space := strings.Repeat(" ", 30-len(k))
		vOf := reflect.ValueOf(v)
		fmt.Println("GET :", k, space, "->", runtime.FuncForPC(vOf.Pointer()).Name())
	}

	goji.Handle(url+"*", w)
	return w
}
コード例 #25
0
ファイル: main.go プロジェクト: DisruptiveMind/throttler
func main() {
	// Limit to 5 requests globally.
	goji.Use(throttler.Limit(5))

	// Limit /admin route to 2 requests.
	admin := web.New()
	admin.Use(throttler.Limit(2))
	admin.Get("/*", handler)

	goji.Handle("/admin/*", admin)
	goji.Get("/*", handler)

	fmt.Printf("Try running the following commands (in different terminal):\n\n")
	fmt.Printf("for i in `seq 1 10`; do (curl 127.0.0.1:8000/ &); done\n\n")
	fmt.Printf("for i in `seq 1 10`; do (curl 127.0.0.1:8000/admin/ &); done\n\n")

	goji.Serve()
}
コード例 #26
0
ファイル: main.go プロジェクト: BlueJello/crud_sample
func main() {

	log.Printf(`main`)

	user := web.New()
	goji.Handle("/user/*", user)
	goji.Get("/css/*", http.FileServer(http.Dir(".")))
	goji.Get("/js/*", http.FileServer(http.Dir(".")))

	user.Use(middleware.SubRouter)
	user.Get("/", UserIndex)
	user.Get("/index", UserIndex)
	user.Get("/new", UserNew)
	user.Post("/new", UserCreate)
	user.Get("/edit/:id", UserEdit)
	user.Post("/update/:id", UserUpdate)
	user.Get("/delete/:id", UserDelete)

	goji.Serve()
}
コード例 #27
0
func main() {

	dstURL := "http://127.0.0.1:8080"
	dst, err := url.Parse(dstURL)
	if err != nil {
		log.Fatalln(err)
	}
	proxyHandler := httputil.NewSingleHostReverseProxy(dst)

	goji.Use(func(c *web.C, h http.Handler) http.Handler {
		fn := func(w http.ResponseWriter, r *http.Request) {
			pp.Println(r.Header)
			pp.Println(r.Cookies())
			h.ServeHTTP(w, r)
		}
		return http.HandlerFunc(fn)
	})

	goji.Handle("/*", proxyHandler)
	goji.Serve()
}
コード例 #28
0
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	rand.Seed(time.Now().UnixNano())

	port := os.Getenv("PORT")

	if port != "" {
		flag.Set("bind", ":"+port)
	}

	goji.Get("/", root)
	goji.Get("/health", health)

	authenticated := web.New()
	authenticated.Use(secured)
	goji.Handle("/simulation", authenticated)
	authenticated.Post("/simulation", simulateHandler)

	log.Println("Booting retirement simulation server on port", port)
	goji.Serve()
}
コード例 #29
0
ファイル: main.go プロジェクト: fusikky/go_bbs
func main() {

	index := web.New()
	goji.Handle("/*", index)

	index.Use(middleware.SubRouter)

	index.Get("/", controllers.IndexCtrl)

	index.Get("/post/bbs", controllers.BbsView)
	index.Post("/post/create", services.CreatePost)
	index.Get("/post/edit/:id", controllers.EditPost)
	index.Get("/post/new", controllers.NewPost)
	index.Post("/post/update/:id", services.UpdatePost)
	index.Get("/post/delete/:id", services.DeletePost)

	index.Get("/user/new", controllers.NewUser)
	index.Post("/user/create", services.CreateUser)

	index.Get("/user/login", controllers.Login)
	index.Post("/user/login", services.Login)

	goji.Serve()
}
コード例 #30
0
ファイル: api.go プロジェクト: ivanol/grapi
// New returns a new Grapi object intialised with options. Options must contain
// a value for Db, and if the inbuilt authentication is being used should contain
// a value for JwtKey and LoginModel.
func New(o Options) *Grapi {
	if o.Db == nil {
		panic("Must provide a non nil Db object in the options for a new Grapi")
	}
	if o.UriPrefix == "" {
		o.UriPrefix = "/api"
	}
	if o.UriPrefix[0] != '/' {
		o.UriPrefix = "/" + o.UriPrefix
	}
	o.UriPrefix = strings.TrimSuffix(o.UriPrefix, "/")

	gj := web.New()
	gj.Use(middleware.RequestID)
	if o.LogLevel > 0 {
		gj.Use(middleware.Logger)
	}
	gj.Use(middleware.Recoverer)
	gj.Use(middleware.AutomaticOptions)

	goji.Handle(o.UriPrefix, gj)
	api := Grapi{router: gj, options: &o, db: o.Db}
	return &api
}