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/flash"
)
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 := flash.NewRouter()
a := r.PathPrefix("/api/v1")
// see Route.Route for more info
a.Resource("/pages", &Pages{}, auth)
// see Route.FileServer for more info
r.PathPrefix("/images/").FileServer("./public/")
r.HandleFunc("/", indexHandler)
http.ListenAndServe(":8080", r)
}
// simple quthentication implementation
func auth(c *flash.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 {
flash.Ctx
}
// Index processed on GET /pages
func (p *Pages) Index() {
var res []*Page
for _, v := range pages {
res = append(res, v)
}
p.RenderJSON(200, flash.JSON{"pages": res})
}
// Show processed on GET /pages/1
func (p *Pages) Show() {
page := findPage(p.ID64())
if page == nil {
p.RenderJSONError(404, "record not found")
return
}
p.RenderJSON(200, flash.JSON{"page": page})
}
// Create processed on POST /pages
// with input data provided {"page":{"name":"New Page","content":"some content"}}
func (p *Pages) Create() {
m := Page{}
if m.Name == "" {
// see Request.LoadJSONRequest for more info
p.LoadJSONRequest("page", &m)
p.RenderJSONError(422, "name required")
} else {
insertPage(m)
p.RenderJSON(200, flash.JSON{"page": m})
}
}
// Update processed on PUT /pages/1
// with input data provided {"page":{"name":"Page 1","content":"updated content"}}
func (p *Pages) Update() {
page := findPage(p.ID64())
if page == nil {
p.RenderJSONError(404, "record not found")
return
}
m := Page{}
p.LoadJSONRequest("page", &m)
page.Content = m.Content
p.RenderJSON(200, flash.JSON{"page": page})
}
// Destroy processed on DELETE /pages/1
func (p *Pages) Destroy() {
page := findPage(p.ID64())
if page == nil {
p.RenderJSONError(404, "record not found")
return
}
delete(pages, page.Id)
p.RenderJSON(203, flash.JSON{})
}
// POSTActivate custom non crud action activates/deactivated page. processed on POST /pages/1/activate
func (p *Pages) POSTActivate() {
page := findPage(p.ID64())
if page == nil {
p.RenderJSONError(404, "record not found")
return
}
page.Visible = !page.Visible
p.RenderJSON(200, flash.JSON{"page": page})
}
Its possible to serve custom actions. To add custom action to controller prefix action name with HTTP method:
// POST /pages/clean or POST /pages/1/clean
func (p *Pages) POSTClean {
// do some work here
}
// DELETE /pages/clean or DELETE /pages/1/clean
func (p *Pages) DELETEClean {
// do some work here
}
// GET /pages/stat or GET /pages/1/stat
func (p *Pages) GETStat {
// do some work here
}
...
Index ¶
- func RenderJSON(w http.ResponseWriter, code int, s JSON)
- func RenderJSONError(w http.ResponseWriter, code int, s string)
- func RenderJSONgzip(w http.ResponseWriter, code int, s JSON)
- type BaseModel
- type Controller
- type Ctr
- type Ctx
- func (c *Ctx) Cookie(s string) string
- func (c *Ctx) Header(s string) string
- func (c *Ctx) ID64() int64
- func (c *Ctx) LoadFile(field, dir string) (string, error)
- func (c *Ctx) LoadJSONRequest(root string, v interface{})
- func (c *Ctx) Param(k string) string
- func (c *Ctx) Params() map[string]string
- func (c *Ctx) QueryParam(s string) string
- func (c *Ctx) Render(code int, b []byte)
- func (c *Ctx) RenderError(code int, s string)
- func (c *Ctx) RenderJSON(code int, s JSON)
- func (c *Ctx) RenderJSONError(code int, s string)
- func (c *Ctx) RenderString(code int, s string)
- func (c *Ctx) SetVar(k string, v interface{})
- func (c *Ctx) Var(k string) interface{}
- type JSON
- type Model
- 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 ModelErrors
- type ReqFunc
- type Route
- func (r *Route) FileServer(path string, b ...bool)
- func (r *Route) HandleFunc(s string, f func(http.ResponseWriter, *http.Request))
- func (r *Route) Handler(handler http.Handler) *Route
- func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route
- func (r *Route) NewRoute(prefix string) *Route
- func (r *Route) Resource(path string, i Ctr, funcs ...ReqFunc)
- func (r *Route) Route(path string, f handlerFunc, funcs ...ReqFunc)
- type Router
- func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, *http.Request))
- func (r *Router) HandlePrefix(path string, handler http.Handler)
- func (r *Router) NewRoute(prefix string) *Route
- func (r *Router) PathPrefix(s string) *Route
- func (r *Router) Resource(path string, i Ctr, funcs ...ReqFunc)
- func (r *Router) Route(path string, f handlerFunc, funcs ...ReqFunc)
- func (r *Router) Serve(bind string)
- func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RenderJSON ¶
func RenderJSON(w http.ResponseWriter, code int, s JSON)
RenderJSON common function to render JSON to client
func RenderJSONError ¶
func RenderJSONError(w http.ResponseWriter, code int, s string)
RenderJSONError common function to render error to client in JSON format
func RenderJSONgzip ¶
func RenderJSONgzip(w http.ResponseWriter, code int, s JSON)
RenderJSONgzip common function to render gzipped JSON to client
Types ¶
type BaseModel ¶
type BaseModel interface {
ID() int64
Valid() bool
AddError(string, string)
SetErrors(ModelErrors)
GetErrors() ModelErrors
ResetErrors()
}
BaseModel interface
type Controller ¶
type Controller struct {
Ctx
}
Controller contains request information (deprecated use flash.Ctx instead)
type Ctr ¶
type Ctr interface {
// contains filtered or unexported methods
}
Ctr public interface for Controller
type Ctx ¶
type Ctx struct {
Req *http.Request
W http.ResponseWriter
Action string
// contains filtered or unexported fields
}
Ctx contains request information
func (*Ctx) LoadJSONRequest ¶
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) RenderString ¶
RenderString rendering string to client
type Model ¶
Model structure for base model with ID included
type User struct {
flash.Model
Name string
}
type ModelBase ¶
type ModelBase struct {
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Errors ModelErrors `sql:"-" json:"-"`
}
ModelBase structure for base model
type User struct {
flash.ModelBase
Name string
}
func (*ModelBase) GetErrors ¶
func (m *ModelBase) GetErrors() ModelErrors
GetErrors returns record errors
func (*ModelBase) ResetErrors ¶
func (m *ModelBase) ResetErrors()
ResetErrors clean all model errors
func (*ModelBase) SetErrors ¶
func (m *ModelBase) SetErrors(e ModelErrors)
SetErrors set record 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) 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) HandlerFunc ¶
HandlerFunc sets a handler function for the route.
func (*Route) Resource ¶
Resource registers a new route with a matcher for URL path and registering controller handler 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 ReqFunc.
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("/pages/:id/comments", PageComments, AuthFunc)
where
- PageComments is the function implementing func(*flash.Ctx)
- AuthFunc is middleware function that implements ReqFunc.
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
// contains filtered or unexported fields
}
Router stroring app routes structure
func (*Router) HandleFunc ¶
HandleFunc registers a new route with a matcher for the URL path. See Route.HandlerFunc().
func (*Router) HandlePrefix ¶
HandlePrefix registers a new handler to serve prefix
func (*Router) PathPrefix ¶
PathPrefix create new prefixed group for routes
func (*Router) Resource ¶
Resource registers a new Resource with a matcher for URL path and registering controller handler
