Documentation
¶
Overview ¶
HTTP routing package that helps to create restfull json api for Go applications.
what it does:
- dispatching actions to controllers
- rendering JSON response
- extracting JSON request data by key
- handling file uploads
- sending gzipped JSON responses when applicable
- sending gzipped versions of static files if any
standard REST usage example:
package main
import (
"net/http"
"github.com/vtg/flash2"
)
var pages map[int64]*Page
func main() {
pages = make(map[int64]*Page)
pages[1] = &Page{Id: 1, Name: "Page 1"}
pages[2] = &Page{Id: 2, Name: "Page 2"}
r := flash2.NewRouter()
a := r.PathPrefix("/api/v1")
a.Controller("/pages", Pages{}, auth)
r.PathPrefix("/images").FileServer("./public/")
r.HandleFunc("/", indexHandler)
http.ListenAndServe(":8080", r)
}
//simple quthentication implementation
func auth(c *flash2.Ctx) bool {
key := c.QueryParam("key")
if key == "correct-password" {
return true
} else {
c.RenderJSONError(http.StatusUnauthorized, "unauthorized")
}
return false
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
}
type Page struct {
Id int64 `json:"id"`
Name string `json:"name"`
Content string `json:"content"`
Visible bool `json:"visible"`
}
func findPage(id int64) *Page {
p := pages[id]
return p
}
func insertPage(p Page) *Page {
id := int64(len(pages) + 1)
p.Id = id
pages[id] = &p
return pages[id]
}
//Pages used as controller
type Pages struct{}
//Index processed on GET /pages
func (p Pages) Index(c *flash2.Ctx) {
var res []*Page
for _, v := range pages {
res = append(res, v)
}
c.RenderJSON(200, flash2.JSON{"pages": res})
}
//Show processed on GET /pages/1
func (p Pages) Show(c *flash2.Ctx) {
page := findPage(c.Params.Int64("id"))
if page == nil {
c.RenderJSONError(404, "record not found")
return
}
c.RenderJSON(200, flash2.JSON{"page": page})
}
//Create processed on POST /pages
//with input data provided {"name":"New Page","content":"some content"}
func (p Pages) Create(c *flash2.Ctx) {
m := Page{}
if m.Name == "" {
//see Request.LoadJSONRequest for more info
c.LoadJSONRequest(&m)
c.RenderJSONError(422, "name required")
} else {
insertPage(m)
c.RenderJSON(200, flash2.JSON{"page": m})
}
}
//Update processed on PUT /pages/1
//with input data provided {"name":"Page 1","content":"updated content"}
func (p Pages) Update(c *flash2.Ctx) {
page := findPage(c.Params.Int64("id"))
if page == nil {
c.RenderJSONError(404, "record not found")
return
}
m := Page{}
c.LoadJSONRequest(&m)
page.Content = m.Content
c.RenderJSON(200, flash2.JSON{"page": page})
}
//Destroy processed on DELETE /pages/1
func (p Pages) Destroy(c *flash2.Ctx) {
page := findPage(c.Params.Int64("id"))
if page == nil {
c.RenderJSONError(404, "record not found")
return
}
delete(pages, page.Id)
c.RenderJSON(203, "")
}
//ActivateGET custom non crud action activates/deactivated page. processed on GET /pages/1/activate
func (p Pages) ActivateGET(c *flash2.Ctx) {
page := findPage(c.Params.Int64("id"))
if page == nil {
c.RenderJSONError(404, "record not found")
return
}
page.Visible = !page.Visible
c.RenderJSON(200, flash2.JSON{"page": page})
}
Its possible to serve custom actions. To add custom action to controller add HTTP method suffix to action name:
//POST /pages/clean or POST /pages/1/clean
func (p Pages) CleanPOST {
// do some work here
}
// DELETE /pages/clean or DELETE /pages/1/clean
func (p Pages) CleanDELETE {
// do some work here
}
// GET /pages/stat or GET /pages/1/stat
func (p Pages) StatGET {
// do some work here
}
...
Index ¶
- type BaseModel
- type CtrAction
- type Ctx
- func (c *Ctx) Cookie(s string) string
- func (c *Ctx) Header(s string) string
- func (c *Ctx) LoadFile(field, dir string) (string, error)
- func (c *Ctx) LoadJSONRequest(v interface{})
- func (c *Ctx) Param(k string) string
- func (c *Ctx) QueryParam(s string) string
- func (c *Ctx) Redirect(url string, code int)
- func (c *Ctx) Render(code int, b []byte)
- func (c *Ctx) RenderError(code int, s string)
- func (c *Ctx) RenderJSON(code int, i interface{})
- func (c *Ctx) RenderJSONError(code int, s string)
- func (c *Ctx) RenderRawJSON(code int, b []byte)
- func (c *Ctx) RenderString(code int, s string)
- func (c *Ctx) SetHeader(key, value string)
- func (c *Ctx) SetVar(k string, v interface{})
- func (c *Ctx) Var(k string) interface{}
- type JSON
- type MWFunc
- type ModelBase
- func (m *ModelBase) AddError(f string, t string)
- func (m *ModelBase) GetErrors() modelErrors
- func (m *ModelBase) IsValid() bool
- func (m *ModelBase) ResetErrors()
- func (m *ModelBase) SetErrors(e modelErrors)
- func (m *ModelBase) Valid() bool
- func (m *ModelBase) ValidateFloat32(f string, v, min, max float32)
- func (m *ModelBase) ValidateFloat64(f string, v, min, max float64)
- func (m *ModelBase) ValidateFormat(f, v, reg string)
- func (m *ModelBase) ValidateInt(f string, v, min, max int)
- func (m *ModelBase) ValidateInt64(f string, v, min, max int64)
- func (m *ModelBase) ValidateLength(f, v string, min, max int)
- func (m *ModelBase) ValidatePresence(f, v string)
- type Route
- func (r *Route) Controller(path string, controller interface{}, funcs ...MWFunc)
- func (r *Route) CtrRoute(method, path string, a CtrAction, funcs []MWFunc)
- func (r *Route) Delete(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Route) FileServer(path string, b ...bool)
- func (r *Route) Get(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Route) Handle(path string, handler http.Handler)
- func (r *Route) HandleFunc(s string, f func(http.ResponseWriter, *http.Request))
- func (r *Route) NewRoute(prefix string) *Route
- func (r *Route) Post(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Route) Put(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Route) Route(method, path string, f handlerFunc, funcs ...MWFunc)
- type Router
- func (r *Router) Controller(path string, i interface{}, funcs ...MWFunc)
- func (r *Router) Delete(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Router) Get(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Router) Handle(path string, handler http.Handler)
- func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, *http.Request))
- func (r *Router) NewRoute(prefix string) *Route
- func (r *Router) PathPrefix(s string) *Route
- func (r *Router) Post(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Router) Put(path string, f handlerFunc, funcs ...MWFunc)
- func (r *Router) Route(method, path string, f handlerFunc, funcs ...MWFunc)
- func (r *Router) Serve(bind string)
- func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
- type URLParams
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseModel ¶
type BaseModel interface {
Valid() bool
AddError(string, string)
SetErrors(modelErrors)
GetErrors() modelErrors
ResetErrors()
}
BaseModel interface
type Ctx ¶
type Ctx struct {
Req *http.Request
W http.ResponseWriter
Params params
IP string
Action string
Controller string
// GZipEnabled enable GZIP (default: false)
GZipEnabled bool
// GZipMinBytes minimum size in bytes to encode (default: 0)
GZipMinBytes int
// contains filtered or unexported fields
}
Ctx contains request information
func (*Ctx) LoadJSONRequest ¶
func (c *Ctx) LoadJSONRequest(v interface{})
LoadJSONRequest extracting JSON request by key from request body into interface
func (*Ctx) QueryParam ¶
QueryParam returns URL query param
func (*Ctx) RenderError ¶
RenderError rendering error to client
func (*Ctx) RenderJSON ¶
RenderJSON rendering JSON to client
func (*Ctx) RenderJSONError ¶
RenderJSONError rendering error to client in JSON format
func (*Ctx) RenderRawJSON ¶
RenderRawJSON rendering raw JSON data to client
func (*Ctx) RenderString ¶
RenderString rendering string to client
type ModelBase ¶
type ModelBase struct {
Errors mErrors `sql:"-" json:"-"`
}
ModelBase structure for base model with error valiadtions
type User struct {
ID int64
Name string
flash2.ModelBase
}
func (*ModelBase) GetErrors ¶
func (m *ModelBase) GetErrors() modelErrors
GetErrors returns model errors
func (*ModelBase) ResetErrors ¶
func (m *ModelBase) ResetErrors()
ResetErrors clean all model errors
func (*ModelBase) SetErrors ¶
func (m *ModelBase) SetErrors(e modelErrors)
SetErrors set model errors
func (*ModelBase) Valid ¶
Valid placeholder for validation function
func (u *User) Valid() bool {
u.ValidatePresence("Name", u.Name)
return u.IsValid()
}
func (*ModelBase) ValidateFloat32 ¶
ValidateFloat32 validates float32 min, max. -1 for any
m.ValidateFloat32("number", 10.2, -1, 11)
func (*ModelBase) ValidateFloat64 ¶
ValidateFloat64 validates float64 min, max. -1 for any
m.ValidateFloat64("number", 10.2, -1, 11)
func (*ModelBase) ValidateFormat ¶
ValidateFormat validates string format with regex string
m.ValidateFormat("ip address", u.IP, `\A(\d{1,3}\.){3}\d{1,3}\z`)
func (*ModelBase) ValidateInt ¶
ValidateInt validates int min, max. -1 for any
m.ValidateInt("number", 10, -1, 11) // max 18
func (*ModelBase) ValidateInt64 ¶
ValidateInt64 validates int64 min, max. -1 for any
m.ValidateInt64("number", 10, 6, -1) // min 6
func (*ModelBase) ValidateLength ¶
ValidateLength validates string min, max length. -1 for any
m.ValidateLength("password", m.Password, 6, 18) // min 6, max 18
func (*ModelBase) ValidatePresence ¶
ValidatePresence validates string for presence
m.ValidatePresence("Name", m.Name)
type Route ¶
type Route struct {
// contains filtered or unexported fields
}
Route storing route information
func (*Route) Controller ¶
Controller creates routes for controller ex:
r := api.NewRouter()
api = r.PathPrefix("/api/v1")
api.Resource("/pages", PagesController{}, AuthFunc)
where
- PagesController is the type implementing Controller
- AuthFunc is middleware function that implements MWFunc.
func (*Route) CtrRoute ¶
CtrRoute registers route for controller method ex:
r := api.NewRouter()
api = r.PathPrefix("/api/v1")
api.CtrRoute("GET","/pages/:id/comments", CtrAction{
Func: pages.Comments,
Name: 'comments',
Controller: "pages",
}, AuthFunc)
where
- AuthFunc is middleware function that implements MWFunc.
func (*Route) FileServer ¶
FileServer provides static files serving ex:
r := api.NewRouter()
dirIndex := false
preferGzip := false
r.PathPrefix("/images/").FileServer("./public", dirIndex, preferGzip)
where
- dirIndex specifying if it should display directory content or not
- preferGzip specifying if it should look for gzipped file version
func (*Route) HandleFunc ¶
HandleFunc setting function to handle route
func (*Route) Route ¶
Route registers a new route with a matcher for URL path ex:
r := api.NewRouter()
api = r.PathPrefix("/api/v1")
api.Route("GET","/pages/:id/comments", PageComments, AuthFunc)
where
- PageComments is the function implementing func(*flash2.Ctx)
- AuthFunc is middleware function that implements MWFunc.
type Router ¶
type Router struct {
// SSL defines server type (default none SSL)
SSL bool
// PublicKey for SSL processing
PublicKey string
// PrivateKey for SSL processing
PrivateKey string
// LogWriter log writer interface
LogWriter io.Writer
LogHTTP bool
HandlerNotFound http.Handler
// contains filtered or unexported fields
}
Router stroring app routes structure
func (*Router) Controller ¶
Controller registers a new Controller with a matcher for URL path See Route.Controller()
func (*Router) HandleFunc ¶
HandleFunc registers a new route with a matcher for the URL path. See Route.HandlerFunc().
func (*Router) PathPrefix ¶
PathPrefix create new prefixed group for routes
