Comments (11)
I tried to implement something along the lines of mikebthun/negronicql but I couldn't get it to work. Here's what I tried:
package renderer
import (
"github.com/gorilla/context"
"gopkg.in/unrolled/render.v1"
"net/http"
)
type RenderMiddleware struct {
Render *render.Render
}
func New(render *render.Render) *RenderMiddleware {
return &RenderMiddleware{render}
}
func (render RenderMiddleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
// Attach the renderer
context.Set(r, "Render", render.Render)
// Call the next middleware handler
next(rw, r)
}
Then in my package main
I have:
render := render.New(render.Options{})
renderer := renderer.New(render)
n.Use(renderer)
Then I can successfully use render := context.Get(r, "Render")
later, but when I try to use render.JSON()
I get this:
render.JSON undefined (type interface {} has no field or method JSON)
It's getting pretty late here, so I'm probably missing something obvious, in which case, if I work it out tomorrow morning, I'll post the answer here and close the ticket. :-)
from render.
Arg, found it. I knew it was something simple and stupid. Instead of render := context.Get(r, "Render")
I need to use render := context.Get(req, "Render").(*render.Render)
. I knew it was simple. :-)
from render.
Glad you got it figured out!
from render.
Is this an advised solution? I've been trying to figure out the same thing, but it seems weird to attach an existing renderer on every single call to a middleware handler?
from render.
While the solution above works, I personally have taken a different approach in most of my apps. Just like you would normally create a global DB
variable somewhere and always refer to that, I create a Render
variable somewhere convenient and use that:
// Render is the global renderer for all views.
var Render *render.Render
// Then you can initialize it or add this to a setup method elsewhere.
func init() {
Render = render.New(render.Options{
// options live here
})
}
from render.
Awesome, thanks a bunch!
from render.
@unrolled Thanks for sharing your example, really helpful. Are there any multi threading considerations here? Is Render threadsafe? In your example, it would be possible for two simultaneous executions of Render.JSON()
, are there any variables which might cause issues there?
I'm super new to Go, so you probably know the idioms better than me. Is creating a single DB variable the idiomatic approach? I saw the negronicql package attaching the DB handler to the session, but that may be the exception rather than the norm. I'd be grateful for any opinion you want to share.
from render.
My very inexperienced and pretty crude reading of the render.go and engine.go code didn't find any potential thread conflicts, but I don't understand the paradigm nearly well enough to be anything like confident in my conclusion.
I'd guess if it's not possible to set any options after the Render instance has been created, then it's probably thread safe by default, but I'll wait for your reply @unrolled before jumping to any conclusions. :-)
from render.
A global render.Render
object is threadsafe. Once it is initialized, the package is basically static. So no worries regarding race conditions or simultaneous executions.
For the DB variable, I would yes it's idiomatic to create a single instance and refer to that from everywhere. Be sure to refer to the global variable rather than passing the pointer along though, passing the pointer could led to issues if something changes the global variable.
A good example of this can be found here: https://github.com/sourcegraph/thesrc/blob/master/datastore/db.go
from render.
Can anyone help me Plz!
I want to make a separate package for routers and put all of my routes into this package and access them in my main package, according to url request, i'm using mux for routing and net/http.
Here is my main.go from Main Package
package main
import (
"RESTMONGOMVC/controllers"
"log"
"net/http"
"github.com/gorilla/mux"
"gopkg.in/mgo.v2"
)
var (
session *mgo.Session
collection *mgo.Collection
err error
)
func getSession() *mgo.Session {
// Connect to our local mongo
s, err := mgo.Dial("mongodb://localhost")
// Check if connection error, is mongo running?
if err != nil {
panic(err)
}
// Deliver session
return s
}
func main() {
var err error
r := mux.NewRouter()
uc := controllers.NewNoteController(getSession())
r.HandleFunc("/api/notes", uc.GetNotes).Methods("GET")
r.HandleFunc("/api/notes", uc.CreateNote).Methods("POST")
r.HandleFunc("/api/notes/{id}", uc.UpdateNote).Methods("PUT")
r.HandleFunc("/api/notes/{id}", uc.DeleteNote).Methods("DELETE")
http.Handle("/api/", r)
http.Handle("/", http.FileServer(http.Dir(".")))
log.Println("Starting Mongodb Session")
session, err = mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
collection = session.DB("notesdb").C("notes")
log.Println("Listening on 8080")
http.ListenAndServe(":8080", nil)
}
from render.
You can just export the *http.ServeMux
represented by your r
variable.
i.e.
package handler
// You could also pass in an *Env struct that embeds your mgo connection and other
// "application wide" services that your routes need to use.
func Routes(session *mgo.Session) *http.ServeMux {
r := mux.NewRouter()
uc := controllers.NewNoteController(getSession())
r.HandleFunc("/api/notes", uc.GetNotes).Methods("GET")
r.HandleFunc("/api/notes", uc.CreateNote).Methods("POST")
r.HandleFunc("/api/notes/{id}", uc.UpdateNote).Methods("PUT")
r.HandleFunc("/api/notes/{id}", uc.DeleteNote).Methods("DELETE")
http.Handle("/api/", r)
// Truncated for brevity
return r
}
... and in your main package:
package main
func main() {
r := handler.Routes(getSession())
// Pass your `http.ServeMux` to ListenAndServe
http.ListenAndServe(":8080", r)
}
Basic example but I hope that's clear. Further questions might be better off asked on https://groups.google.com/forum/?fromgroups#!forum/golang-nuts or http://stackoverflow.com/questions/tagged/go
from render.
Related Issues (20)
- Question: is it possible to change the API of the Render struct to allow setters? HOT 3
- Question: is it possible to set html/template options? HOT 2
- Bot
- Set custom JSON Content-Type HOT 3
- Problem is http response HOT 1
- Define partial in a shared component HOT 1
- Asset and AssetNames render.Options fields HOT 1
- Question: how to access partial name HOT 4
- StreamingJSON does nothing / information in README is false HOT 1
- json how to use JSONNumber HOT 1
- Ask about Renderer.Text() HOT 2
- Tag the current and future releases HOT 1
- partial wrong number of args HOT 1
- How to use the HTML type HOT 1
- Template Functions added via HTMLOptions don't seem to work HOT 5
- FR: Support templates for JSON renderer HOT 2
- BufferPool leads to wasted memory HOT 3
- Render templates from `embed.FS`
- Example of Embedded FS support is missing package name HOT 2
- UnescapeHTML can render un-parseable JSON HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from render.