README

#Neko wercker status GoDoc GoCover

A lightweight web application framework for Golang

NOTE: Neko is still under development, so API might be changed in future.

Features

  • Extremely simple to use.
  • RESTful support
  • Middleware support
  • Unlimited nested group routers.

Getting Started

Basic usage

package main
import "github.com/rocwong/neko"
func main() {
  app := neko.Classic()
  app.GET("/", func(ctx *neko.Context)  {
      ctx.Text("Hello world!")
  })
  app.Run(":3000")
}

Initial Neko without middlewares

app := neko.New()
app.Use(neko.Logger())
app.Use(neko.Recovery())

##Routing Using GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS and Any

app.GET("/get", get)
app.POST("/post", post)
app.PUT("/put", put)
app.PATCH("/patch", patch)
app.DELETE("/delete", delete)
app.HEAD("/head", head)
app.OPTIONS("/options", options)
// A shortcut for all request methods
app.Any("/any", options)

Neko uses julienschmidt's httprouter internaly.

##Group Routing

v1 := app.Group("/v1", func(router *neko.RouterGroup) {
  // Match /v1/item
  router.GET("/item", item)

  // Nested group
  router.Group("/sub", func(sub *neko.RouterGroup) {
    // Match /v1/sub/myitem
    sub.GET("/myitem", myitem)
  })
})
// Match /v1/act
v1.GET("/act", act)

Parameters

####Parameters in path

app.GET("/user/:name/*age", func(ctx *neko.Context) {
  // Request: "/user/neko/1?name=none&food=fish"
  
  name := ctx.Params.ByGet("name")
  age := ctx.Params.ByGet("age")
  food := ctx.Params.ByGet("food")
  
  // Response: neko is 1, eat fish
  ctx.Text(name + " is " + age + ", eat " + ctx.Params.ByGet("eat"))
})

####Multipart/Urlencoded Form

app.POST("/user", func(ctx *neko.Context) {
  // Request: "/user"  Post Data: { name: neko, age: 1}
  
  // Response: neko is 1
  ctx.Text(ctx.Params.ByPost("name") + " is " + ctx.Params.ByPost("age"))
})

####Json Data

app.POST("/user", func(ctx *neko.Context) {
  // Request: "/user"  Post Data: { name: neko, age: 1} Content-type: "application/json"
  
  // Only get once
  dataJson := ctx.Params.Json()
  
  // Response: neko is 1
  ctx.Text(dataJson.GetString("name") + " is " + dataJson.Get("age"))
  
  // dataJson.Get(param) : return type interface {}
  // dataJson.GetString(param) : return type string
  // dataJson.GetInt32(param) : return type int32
  // dataJson.GetUInt32(param) : return type uint32
  // dataJson.GetFloat32(param) : return type float32
  // dataJson.GetFloat64(param) : return type float64
})

####BindJSON

type User struct {
  User     string
  Password string
}
app.POST("/user", func(ctx *neko.Context) {
  // Request: "/user"  Post Data: { name: neko, password: abcdefg} Content-type: "application/json"
  var json User
  if ctx.Params.BindJSON(&json) == nil {
    // Response: neko's password abcdefg
    ctx.Text(json.Name + "'s password " + json.Password)
  }
})

##Response

####Render

type ExampleXml struct {
  XMLName xml.Name `xml:"example"`
  One     string   `xml:"one,attr"`
  Two     string   `xml:"two,attr"`
}

// Response: <example one="hello" two="xml"/>
ctx.Xml(ExampleXml{One: "hello", Two: "xml"})
// Response: {"msg": "json render", "status": 200}
ctx.Json(neko.JSON{"msg": "json render", "status": 200})

// Response: neko({"msg": "json render", "status": 200})
ctx.Jsonp("neko", neko.JSON{"msg": "json render", "status": 200})

// Response: neko text
ctx.Text("neko text")

####Redirect

// Default 302
ctx.Redirect("/")

// Redirect 301
ctx.Redirect("/", 301)

####Headers

// Get header
ctx.Writer.Header()

// Set header
ctx.SetHeader("x-before", "before")

##Cookie

app.GET("/", func (ctx *neko.Context) {
  ctx.SetCookie("myvalue", "Cookies Save")
  ctx.Text("Cookies Save")
})

app.GET("/get", func (ctx *neko.Context) {
  ctx.Text(ctx.GetCookie("myvalue"))
})

####Secure cookie

// Set cookie secret
app.SetCookieSecret("secret123")

app.GET("/set-secure", func (ctx *neko.Context) {
  ctx.SetSecureCookie("sv", "Cookies Save")
  ctx.Text("Cookies Save")
})

app.GET("/get-secure", func (ctx *neko.Context) {
  ctx.Text(ctx.GetSecureCookie("sv"))
})

Use following arguments order to set more properties:

SetCookie/SetCookieSecret(name, value [, MaxAge, Path, Domain, Secure, HttpOnly]).

Middlewares

####Using middlewares

// Global middlewares
app.Use(neko.Logger())

// Per route middlewares, you can add as many as you desire.
app.Get("/user", mymiddleware(), mymiddleware2(), user)

// Pass middlewares to groups
v1 := app.Group("/v1", func(router *neko.RouterGroup) {
  router.GET("/item", item)
}, mymiddleware1(), mymiddleware2(), mymiddleware3())

v1.Use(mymiddleware4)

####Custom middlewares

func mymiddleware() neko.HandlerFunc {
  return func (ctx *neko.Context) {
    // Before request
    t := time.Now()

    ctx.Next()

    // After request
    latency := time.Since(t)
    log.Print(latency)

    // Access the status we are sending
    status := ctx.Writer.Status()
    log.Println(status)
  }
}
More middleware

For more middleware and functionality, check out the repositories in the neko-contrib organization.

Others

// Static Serves
app.Static("/static", "content/static")

// Get Remote IP Address
app.GET("/", func (ctx *neko.Context) {
  ctx.ClientIP()
}

// Metadata Management
app.GET("/", func (ctx *neko.Context) {
  ctx.Set("foo", "bar")
  v, err := ctx.Get("foo")
  v = ctx.MustGet("foo")
}

Credits & Thanks

I use code/got inspiration from these excellent libraries:

License

Neko is licensed under the MIT

Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const (
	DEV  string = "development"
	PROD string = "production"
	TEST string = "test"
)

Variables

View Source
var NekoEnv = DEV

NekoEnv is the environment that Neko is executing in. The NEKO_ENV is read on initialization to set this variable.

Functions

func Version

func Version() string

Types

type Context

type Context struct {
	Writer  ResponseWriter
	Req     *http.Request
	Session Session
	Keys    map[string]interface{}
	Params  routerParams
	Engine  *Engine

	HtmlEngine
	// contains filtered or unexported fields
}

func (*Context) Abort

func (c *Context) Abort()

Forces the system to do not continue calling the pending handlers in the chain.

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP returns more real IP address.

func (*Context) Get

func (c *Context) Get(key string) (interface{}, error)

Get returns the value for the given key or an error if the key does not exist.

func (*Context) GetBasicSecureCookie

func (ctx *Context) GetBasicSecureCookie(Secret, name string) (string, bool)

GetBasicSecureCookie returns given cookie value from request header with secret string.

func (*Context) GetCookie

func (c *Context) GetCookie(name string) string

GetCookie returns given cookie value from request header.

func (*Context) GetSecureCookie

func (ctx *Context) GetSecureCookie(name string) (string, bool)

GetSecureCookie returns given cookie value from request header with default secret string.

func (*Context) Json

func (c *Context) Json(data interface{}, status ...int)

Serializes the given struct as JSON into the response body in a fast and efficient way. It also sets the Content-Type as "application/json".

func (*Context) Jsonp

func (c *Context) Jsonp(callback string, data interface{}, status ...int)

Serializes the given struct as JSONP into the response body in a fast and efficient way. It also sets the Content-Type as "application/javascript".

func (*Context) MustGet

func (c *Context) MustGet(key string) interface{}

MustGet returns the value for the given key or panics if the value doesn't exist.

func (*Context) Next

func (c *Context) Next()

Next should be used only in the middlewares. It executes the pending handlers in the chain inside the calling handler.

func (*Context) Redirect

func (c *Context) Redirect(location string, status ...int)

Redirect returns a HTTP redirect to the specific location. default for 302

func (*Context) Set

func (c *Context) Set(key string, item interface{})

Sets a new pair key/value just for the specified context.

func (*Context) SetBasicSecureCookie

func (ctx *Context) SetBasicSecureCookie(Secret, name, value string, others ...interface{})

SetBasicSecureCookie sets given cookie value to response header with secret string.

func (*Context) SetCookie

func (c *Context) SetCookie(name, value string, others ...interface{})

SetCookie sets given cookie value to response header. ctx.SetCookie(name, value [, MaxAge, Path, Domain, Secure, HttpOnly])

func (*Context) SetHeader

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

SetHeader sets a response header.

func (*Context) SetSecureCookie

func (ctx *Context) SetSecureCookie(name, value string, others ...interface{})

SetSecureCookie sets given cookie value to response header with default secret string.

func (*Context) Text

func (c *Context) Text(data string, status ...int)

Writes the given string into the response body and sets the Content-Type to "text/plain".

func (*Context) Xml

func (c *Context) Xml(data interface{}, status ...int)

Serializes the given struct as XML into the response body in a fast and efficient way. It also sets the Content-Type as "application/xml".

type Engine

type Engine struct {
	*RouterGroup
	AppName string
	// contains filtered or unexported fields
}

func Classic

func Classic(appName ...string) *Engine

Classic creates a classic Neko with some basic default middleware - neko.Logger and neko.Recovery.

func New

func New() *Engine

New returns a new blank Engine instance without any middleware attached.

func (*Engine) Run

func (c *Engine) Run(addr string) error

Run run the http server.

func (*Engine) RunTLS

func (c *Engine) RunTLS(addr string, cert string, key string) error

Run run the https server.

func (*Engine) ServeHTTP

func (c *Engine) ServeHTTP(res http.ResponseWriter, req *http.Request)

ServeHTTP makes the router implement the http.Handler interface.

func (*Engine) SetCookieSecret

func (m *Engine) SetCookieSecret(secret string)

SetCookieSecret sets global default secure cookie secret.

func (*Engine) Use

func (c *Engine) Use(middlewares ...HandlerFunc)

type HandlerFunc

type HandlerFunc func(*Context)

func Logger

func Logger() HandlerFunc

func Recovery

func Recovery() HandlerFunc

Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.

type HtmlEngine

type HtmlEngine interface {
	Render(view string, context interface{}, status ...int) error
}

HtmlEngine is an interface for parsing html templates and redering HTML.

type JSON

type JSON map[string]interface{}

type ResponseWriter

type ResponseWriter interface {
	http.ResponseWriter
	http.Flusher
	Status() int
	// Size returns the size of the response body.
	Size() int
	Written() bool
	WriteHeaderNow()
	// Before allows for a function to be called before the ResponseWriter has been written to. This is
	// useful for setting headers or any other operations that must happen before a response has been written.
	Before(func(ResponseWriter))
}

type RouterGroup

type RouterGroup struct {
	Handlers []HandlerFunc
	// contains filtered or unexported fields
}

func (*RouterGroup) Any

func (c *RouterGroup) Any(relativePath string, handlers ...HandlerFunc)

Any is a shortcut for all request methods

func (*RouterGroup) DELETE

func (c *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc)

DELETE is a shortcut for router.Handle("DELETE", path, handle)

func (*RouterGroup) GET

func (c *RouterGroup) GET(relativePath string, handlers ...HandlerFunc)

GET is a shortcut for router.Handle("GET", path, handle)

func (*RouterGroup) Group

func (c *RouterGroup) Group(relativePath string, fn func(*RouterGroup), handlers ...HandlerFunc) *RouterGroup

Creates a new router group. You should add all the routes that have common middlwares or the same path prefix. For example, all the routes that use a common middlware for authorization could be grouped.

func (*RouterGroup) HEAD

func (c *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc)

HEAD is a shortcut for router.Handle("HEAD", path, handle)

func (*RouterGroup) Handle

func (c *RouterGroup) Handle(httpMethod, relativePath string, handlers []HandlerFunc)

Handle registers a new request handle and middlewares with the given path and method. The last handler should be the real handler, the other ones should be middlewares that can and should be shared among different routes.

For GET, POST, PUT, PATCH and DELETE requests the respective shortcut functions can be used.

This function is intended for bulk loading and to allow the usage of less frequently used, non-standardized or custom methods (e.g. for internal communication with a proxy).

func (*RouterGroup) OPTIONS

func (c *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc)

OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle)

func (*RouterGroup) PATCH

func (c *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc)

PATCH is a shortcut for router.Handle("PATCH", path, handle)

func (*RouterGroup) POST

func (c *RouterGroup) POST(relativePath string, handlers ...HandlerFunc)

POST is a shortcut for router.Handle("POST", path, handle)

func (*RouterGroup) PUT

func (c *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc)

PUT is a shortcut for router.Handle("PUT", path, handle)

func (*RouterGroup) Static

func (c *RouterGroup) Static(path, dir string)

Static serves files from the given file system root. Internally a http.FileServer is used, therefore http.NotFound is used instead of the Router's NotFound handler. To use the operating system's file system implementation, use : router.Static("/static", "/var/www")

func (*RouterGroup) Use

func (c *RouterGroup) Use(middlewares ...HandlerFunc)

Adds middlewares to the group

type Session

type Session interface {
	Get(key interface{}) interface{}
	Set(key interface{}, val interface{})
	Delete(key interface{})
	Clear()
	AddFlash(value interface{}, vars ...string)
	Flashes(vars ...string) []interface{}
	Options(SessionOptions)
}

Session stores the values and optional configuration for a session.

type SessionOptions

type SessionOptions struct {
	Path     string
	Domain   string
	MaxAge   int
	Secure   bool
	HTTPOnly bool
}

SessionOptions stores configuration for a session or session store.

type SessionStore

type SessionStore interface {
	sessions.Store
	Options(SessionOptions)
}

SessionStore is an interface for custom session stores.

Directories

Path Synopsis
render