flash2

package module
v0.0.0-...-6b6007d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2016 License: MIT Imports: 15 Imported by: 0

README

flash2

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

Routing:

r := flash2.NewRouter()

// GET route to function(*Ctx)
r.Get("/pages/:id", ShowPage)

// auto generates controller routes
r.Controller("/pages", PagesController{})

// standard http handler
r.HandleFunc("/", IndexHandler)

URL Parameters:

// prefixed with ':' are strict params. all parts should be present in request
// strict params can't be used after optional or global params
// Request: '/pages/1/act' Returns: [id:1, action:act]
// Request: '/pages/1' Returns: not found
"/pages/:id/:action"

// prefixed with '@' are global params. global param returns the rest of request
// global param can only be used as last param
// Request: '/files/path_to/file.go' Returns: [name:"path_to/file.go"]
"/files/@name"

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
 }
 ...

#####Author

VTG - http://github.com/vtg

License

Released under the MIT License.

GoDoc

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

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 CtrAction

type CtrAction struct {
	Func       handlerFunc
	Name       string
	Controller string
}

CtrAction type for CtrRoute

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) Cookie

func (c *Ctx) Cookie(s string) string

Cookie returns request header

func (*Ctx) Header

func (c *Ctx) Header(s string) string

Header returns request header

func (*Ctx) LoadFile

func (c *Ctx) LoadFile(field, dir string) (string, error)

LoadFile handling file uploads

func (*Ctx) LoadJSONRequest

func (c *Ctx) LoadJSONRequest(v interface{})

LoadJSONRequest extracting JSON request by key from request body into interface

func (*Ctx) Param

func (c *Ctx) Param(k string) string

Param get URL param

func (*Ctx) QueryParam

func (c *Ctx) QueryParam(s string) string

QueryParam returns URL query param

func (*Ctx) Redirect

func (c *Ctx) Redirect(url string, code int)

Redirect http redirect

func (*Ctx) Render

func (c *Ctx) Render(code int, b []byte)

Render rendering []byte to client

func (*Ctx) RenderError

func (c *Ctx) RenderError(code int, s string)

RenderError rendering error to client

func (*Ctx) RenderJSON

func (c *Ctx) RenderJSON(code int, i interface{})

RenderJSON rendering JSON to client

func (*Ctx) RenderJSONError

func (c *Ctx) RenderJSONError(code int, s string)

RenderJSONError rendering error to client in JSON format

func (*Ctx) RenderRawJSON

func (c *Ctx) RenderRawJSON(code int, b []byte)

RenderRawJSON rendering raw JSON data to client

func (*Ctx) RenderString

func (c *Ctx) RenderString(code int, s string)

RenderString rendering string to client

func (*Ctx) SetHeader

func (c *Ctx) SetHeader(key, value string)

SetHeader adds header to response

func (*Ctx) SetVar

func (c *Ctx) SetVar(k string, v interface{})

SetVar set session variable

func (*Ctx) Var

func (c *Ctx) Var(k string) interface{}

Var returns session variable

type JSON

type JSON map[string]interface{}

JSON shortcut for map[string]interface{}

type MWFunc

type MWFunc func(*Ctx) bool

MWFunc is the function type for middlware

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) AddError

func (m *ModelBase) AddError(f string, t string)

AddError adding error to model

func (*ModelBase) GetErrors

func (m *ModelBase) GetErrors() modelErrors

GetErrors returns model errors

func (*ModelBase) IsValid

func (m *ModelBase) IsValid() bool

IsValid returns true if no errors on model

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

func (m *ModelBase) Valid() bool

Valid placeholder for validation function

func (u *User) Valid() bool {
	u.ValidatePresence("Name", u.Name)
	return u.IsValid()
}

func (*ModelBase) ValidateFloat32

func (m *ModelBase) ValidateFloat32(f string, v, min, max float32)

ValidateFloat32 validates float32 min, max. -1 for any

m.ValidateFloat32("number", 10.2, -1, 11)

func (*ModelBase) ValidateFloat64

func (m *ModelBase) ValidateFloat64(f string, v, min, max float64)

ValidateFloat64 validates float64 min, max. -1 for any

m.ValidateFloat64("number", 10.2, -1, 11)

func (*ModelBase) ValidateFormat

func (m *ModelBase) ValidateFormat(f, v, reg string)

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

func (m *ModelBase) ValidateInt(f string, v, min, max int)

ValidateInt validates int min, max. -1 for any

m.ValidateInt("number", 10, -1, 11)  // max 18

func (*ModelBase) ValidateInt64

func (m *ModelBase) ValidateInt64(f string, v, min, max int64)

ValidateInt64 validates int64 min, max. -1 for any

m.ValidateInt64("number", 10, 6, -1) // min 6

func (*ModelBase) ValidateLength

func (m *ModelBase) ValidateLength(f, v string, min, max int)

ValidateLength validates string min, max length. -1 for any

m.ValidateLength("password", m.Password, 6, 18) // min 6, max 18

func (*ModelBase) ValidatePresence

func (m *ModelBase) ValidatePresence(f, v string)

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

func (r *Route) Controller(path string, controller interface{}, funcs ...MWFunc)

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

func (r *Route) CtrRoute(method, path string, a CtrAction, funcs []MWFunc)

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) Delete

func (r *Route) Delete(path string, f handlerFunc, funcs ...MWFunc)

Delete shorthand for Route("DELETE", ...)

func (*Route) FileServer

func (r *Route) FileServer(path string, b ...bool)

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) Get

func (r *Route) Get(path string, f handlerFunc, funcs ...MWFunc)

Get shorthand for Route("GET", ...)

func (*Route) Handle

func (r *Route) Handle(path string, handler http.Handler)

Handle adding new route with handler

func (*Route) HandleFunc

func (r *Route) HandleFunc(s string, f func(http.ResponseWriter, *http.Request))

HandleFunc setting function to handle route

func (*Route) NewRoute

func (r *Route) NewRoute(prefix string) *Route

NewRoute registers an empty route.

func (*Route) Post

func (r *Route) Post(path string, f handlerFunc, funcs ...MWFunc)

Post shorthand for Route("POST", ...)

func (*Route) Put

func (r *Route) Put(path string, f handlerFunc, funcs ...MWFunc)

Put shorthand for Route("PUT", ...)

func (*Route) Route

func (r *Route) Route(method, path string, f handlerFunc, funcs ...MWFunc)

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 NewRouter

func NewRouter() *Router

NewRouter creates new Router

func (*Router) Controller

func (r *Router) Controller(path string, i interface{}, funcs ...MWFunc)

Controller registers a new Controller with a matcher for URL path See Route.Controller()

func (*Router) Delete

func (r *Router) Delete(path string, f handlerFunc, funcs ...MWFunc)

Delete shorthand for Route("DELETE", ...)

func (*Router) Get

func (r *Router) Get(path string, f handlerFunc, funcs ...MWFunc)

Get shorthand for Route("GET", ...)

func (*Router) Handle

func (r *Router) Handle(path string, handler http.Handler)

Handle registers a new handler to serve path

func (*Router) HandleFunc

func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, *http.Request))

HandleFunc registers a new route with a matcher for the URL path. See Route.HandlerFunc().

func (*Router) NewRoute

func (r *Router) NewRoute(prefix string) *Route

NewRoute registers an empty route.

func (*Router) PathPrefix

func (r *Router) PathPrefix(s string) *Route

PathPrefix create new prefixed group for routes

func (*Router) Post

func (r *Router) Post(path string, f handlerFunc, funcs ...MWFunc)

Post shorthand for Route("POST", ...)

func (*Router) Put

func (r *Router) Put(path string, f handlerFunc, funcs ...MWFunc)

Put shorthand for Route("PUT", ...)

func (*Router) Route

func (r *Router) Route(method, path string, f handlerFunc, funcs ...MWFunc)

Route registers a new route with a matcher for URL path See Route.Route().

func (*Router) Serve

func (r *Router) Serve(bind string)

Serve starting http server

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP dispatches the handler registered in the matched route.

type URLParams

type URLParams map[string]string

URLParams contains arams parsed from route template

func (URLParams) Bool

func (u URLParams) Bool(k string) bool

Bool returns param value as bool

func (URLParams) Int

func (u URLParams) Int(k string) int

Int returns param value as int

func (URLParams) Int64

func (u URLParams) Int64(k string) int64

Int64 returns param value as int64

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL