Awesome
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