gin

package
v0.0.0-...-e120481 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2015 License: MIT, MIT Imports: 30 Imported by: 0

README

#Gin Web Framework Build Status Coverage Status

GoDoc

Gin is a web framework written in Golang. It features a martini-like API with much better performance, up to 40 times faster thanks to httprouter. If you need performance and good productivity, you will love Gin.

Gin console logger

$ cat test.go
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong")
	})
	r.Run(":8080") // listen and serve on 0.0.0.0:8080
}

Benchmarks

Gin uses a custom version of HttpRouter

See all benchmarks

BenchmarkAce_GithubAll     10000        109482 ns/op       13792 B/op        167 allocs/op
BenchmarkBear_GithubAll    10000        287490 ns/op       79952 B/op        943 allocs/op
BenchmarkBeego_GithubAll        3000        562184 ns/op      146272 B/op       2092 allocs/op
BenchmarkBone_GithubAll      500       2578716 ns/op      648016 B/op       8119 allocs/op
BenchmarkDenco_GithubAll       20000         94955 ns/op       20224 B/op        167 allocs/op
BenchmarkEcho_GithubAll    30000         58705 ns/op           0 B/op          0 allocs/op
BenchmarkGin_GithubAll     30000         50991 ns/op           0 B/op          0 allocs/op
BenchmarkGocraftWeb_GithubAll       5000        449648 ns/op      133280 B/op       1889 allocs/op
BenchmarkGoji_GithubAll     2000        689748 ns/op       56113 B/op        334 allocs/op
BenchmarkGoJsonRest_GithubAll       5000        537769 ns/op      135995 B/op       2940 allocs/op
BenchmarkGoRestful_GithubAll         100      18410628 ns/op      797236 B/op       7725 allocs/op
BenchmarkGorillaMux_GithubAll        200       8036360 ns/op      153137 B/op       1791 allocs/op
BenchmarkHttpRouter_GithubAll      20000         63506 ns/op       13792 B/op        167 allocs/op
BenchmarkHttpTreeMux_GithubAll     10000        165927 ns/op       56112 B/op        334 allocs/op
BenchmarkKocha_GithubAll       10000        171362 ns/op       23304 B/op        843 allocs/op
BenchmarkMacaron_GithubAll      2000        817008 ns/op      224960 B/op       2315 allocs/op
BenchmarkMartini_GithubAll       100      12609209 ns/op      237952 B/op       2686 allocs/op
BenchmarkPat_GithubAll       300       4830398 ns/op     1504101 B/op      32222 allocs/op
BenchmarkPossum_GithubAll      10000        301716 ns/op       97440 B/op        812 allocs/op
BenchmarkR2router_GithubAll    10000        270691 ns/op       77328 B/op       1182 allocs/op
BenchmarkRevel_GithubAll        1000       1491919 ns/op      345553 B/op       5918 allocs/op
BenchmarkRivet_GithubAll       10000        283860 ns/op       84272 B/op       1079 allocs/op
BenchmarkTango_GithubAll        5000        473821 ns/op       87078 B/op       2470 allocs/op
BenchmarkTigerTonic_GithubAll       2000       1120131 ns/op      241088 B/op       6052 allocs/op
BenchmarkTraffic_GithubAll       200       8708979 ns/op     2664762 B/op      22390 allocs/op
BenchmarkVulcan_GithubAll       5000        353392 ns/op       19894 B/op        609 allocs/op
BenchmarkZeus_GithubAll     2000        944234 ns/op      300688 B/op       2648 allocs/op

##Gin v1. stable

  • Zero allocation router.
  • Still the fastest http router and framework. From routing to writing.
  • Complete suite of unit tests
  • Battle tested
  • API frozen, new releases will not break your code.

Start using it

  1. Download and install it:
go get github.com/gin-gonic/gin
  1. Import it in your code:
import "github.com/gin-gonic/gin"

##API Examples

Using GET, POST, PUT, PATCH, DELETE and OPTIONS
func main() {
	// Creates a gin router with default middlewares:
	// logger and recovery (crash-free) middlewares
	router := gin.Default()

	router.GET("/someGet", getting)
	router.POST("/somePost", posting)
	router.PUT("/somePut", putting)
	router.DELETE("/someDelete", deleting)
	router.PATCH("/somePatch", patching)
	router.HEAD("/someHead", head)
	router.OPTIONS("/someOptions", options)

	// Listen and server on 0.0.0.0:8080
	router.Run(":8080")
}
Parameters in path
func main() {
	router := gin.Default()
	
	// This handler will match /user/john but will not match neither /user/ or /user
	router.GET("/user/:name", func(c *gin.Context) {
		name := c.Param("name")
		c.String(http.StatusOK, "Hello %s", name)
	})

	// However, this one will match /user/john/ and also /user/john/send
	// If no other routers match /user/john, it will redirect to /user/join/
	router.GET("/user/:name/*action", func(c *gin.Context) {
		name := c.Param("name")
		action := c.Param("action")
		message := name + " is " + action
		c.String(http.StatusOK, message)
	})
	
	router.Run(":8080")
}
Querystring parameters
func main() {
    router := gin.Default()

    // Query string parameters are parsed using the existing underlying request object.  
    // The request responds to a url matching:  /welcome?firstname=Jane&lastname=Doe
    router.GET("/welcome", func(c *gin.Context) {
        firstname := c.DefaultQuery("firstname", "Guest")
        lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")

        c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
    })
    router.Run(":8080")
}

Multipart/Urlencoded Form

func main() {
    router := gin.Default()

    router.POST("/form_post", func(c *gin.Context) {
        message := c.PostForm("message")
        nick := c.DefaultPostForm("nick", "anonymous")
                
        c.JSON(200, gin.H{
            "status": "posted",
            "message": message,
        })
    })
    router.Run(":8080")
}
Grouping routes
func main() {
	router := gin.Default()

	// Simple group: v1
	v1 := router.Group("/v1")
	{
		v1.POST("/login", loginEndpoint)
		v1.POST("/submit", submitEndpoint)
		v1.POST("/read", readEndpoint)
	}

	// Simple group: v2
	v2 := router.Group("/v2")
	{
		v2.POST("/login", loginEndpoint)
		v2.POST("/submit", submitEndpoint)
		v2.POST("/read", readEndpoint)
	}

	router.Run(":8080")
}
Blank Gin without middlewares by default

Use

r := gin.New()

instead of

r := gin.Default()
Using middlewares
func main() {
	// Creates a router without any middleware by default
	r := gin.New()

	// Global middlewares
	r.Use(gin.Logger())
	r.Use(gin.Recovery())

	// Per route middlewares, you can add as many as you desire.
	r.GET("/benchmark", MyBenchLogger(), benchEndpoint)

	// Authorization group
	// authorized := r.Group("/", AuthRequired())
	// exactly the same than:
	authorized := r.Group("/")
	// per group middlewares! in this case we use the custom created
	// AuthRequired() middleware just in the "authorized" group.
	authorized.Use(AuthRequired())
	{
		authorized.POST("/login", loginEndpoint)
		authorized.POST("/submit", submitEndpoint)
		authorized.POST("/read", readEndpoint)

		// nested group
		testing := authorized.Group("testing")
		testing.GET("/analytics", analyticsEndpoint)
	}

	// Listen and server on 0.0.0.0:8080
	r.Run(":8080")
}
Model binding and validation

To bind a request body into a type, use model binding. We currently support binding of JSON, XML and standard form values (foo=bar&boo=baz).

Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set json:"fieldname".

When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use BindWith.

You can also specify that specific fields are required. If a field is decorated with binding:"required" and has a empty value when binding, the current request will fail with an error.

// Binding from JSON
type LoginJSON struct {
	User     string `json:"user" binding:"required"`
	Password string `json:"password" binding:"required"`
}

// Binding from form values
type LoginForm struct {
    User     string `form:"user" binding:"required"`
    Password string `form:"password" binding:"required"`   
}

func main() {
	r := gin.Default()

    // Example for binding JSON ({"user": "manu", "password": "123"})
	r.POST("/loginJSON", func(c *gin.Context) {
		var json LoginJSON

        c.Bind(&json) // This will infer what binder to use depending on the content-type header.
        if json.User == "manu" && json.Password == "123" {
            c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
        } else {
            c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
        }
	})

    // Example for binding a HTML form (user=manu&password=123)
    r.POST("/loginHTML", func(c *gin.Context) {
        var form LoginForm

        c.BindWith(&form, binding.Form) // You can also specify which binder to use. We support binding.Form, binding.JSON and binding.XML.
        if form.User == "manu" && form.Password == "123" {
            c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
        } else {
            c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
        }
    })

	// Listen and server on 0.0.0.0:8080
	r.Run(":8080")
}

###Multipart/Urlencoded binding

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type LoginForm struct {
	User     string `form:"user" binding:"required"`
	Password string `form:"password" binding:"required"`
}

func main() {

	router := gin.Default()

	router.POST("/login", func(c *gin.Context) {
		// you can bind multipart form with explicit binding declaration:
		// c.BindWith(&form, binding.Form)
		// or you can simply use autobinding with Bind method:
		var form LoginForm
		c.Bind(&form) // in this case proper binding will be automatically selected

		if form.User == "user" && form.Password == "password" {
			c.JSON(200, gin.H{"status": "you are logged in"})
		} else {
			c.JSON(401, gin.H{"status": "unauthorized"})
		}
	})

	router.Run(":8080")

}

Test it with:

$ curl -v --form user=user --form password=password http://localhost:8080/login
XML and JSON rendering
func main() {
	r := gin.Default()

	// gin.H is a shortcut for map[string]interface{}
	r.GET("/someJSON", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
	})

	r.GET("/moreJSON", func(c *gin.Context) {
		// You also can use a struct
		var msg struct {
			Name    string `json:"user"`
			Message string
			Number  int
		}
		msg.Name = "Lena"
		msg.Message = "hey"
		msg.Number = 123
		// Note that msg.Name becomes "user" in the JSON
		// Will output  :   {"user": "Lena", "Message": "hey", "Number": 123}
		c.JSON(http.StatusOK, msg)
	})

	r.GET("/someXML", func(c *gin.Context) {
		c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
	})

	// Listen and server on 0.0.0.0:8080
	r.Run(":8080")
}

####Serving static files

func main() {
    router := gin.Default()
    router.Static("/assets", "./assets")
    router.StaticFS("/more_static", http.Dir("my_file_system"))
    router.StaticFile("/favicon.ico", "./resources/favicon.ico")

    // Listen and server on 0.0.0.0:8080
    router.Run(":8080")
}

####HTML rendering

Using LoadHTMLTemplates()

func main() {
	router := gin.Default()
	router.LoadHTMLGlob("templates/*")
	//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
	router.GET("/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.tmpl", gin.H{
			"title": "Main website",
		})
	})
	router.Run(":8080")
}
<html><h1>
	{{ .title }}
</h1>
</html>

You can also use your own html template render

import "html/template"

func main() {
	router := gin.Default()
	html := template.Must(template.ParseFiles("file1", "file2"))
	router.SetHTMLTemplate(html)
	router.Run(":8080")
}
Redirects

Issuing a HTTP redirect is easy:

r.GET("/test", func(c *gin.Context) {
	c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
})

Both internal and external locations are supported.

Custom Middlewares
func Logger() gin.HandlerFunc {
	return func(c *gin.Context) {
		t := time.Now()

		// Set example variable
		c.Set("example", "12345")

		// before request

		c.Next()

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

		// access the status we are sending
		status := c.Writer.Status()
		log.Println(status)
	}
}

func main() {
	r := gin.New()
	r.Use(Logger())

	r.GET("/test", func(c *gin.Context) {
		example := c.MustGet("example").(string)

		// it would print: "12345"
		log.Println(example)
	})

	// Listen and server on 0.0.0.0:8080
	r.Run(":8080")
}
Using BasicAuth() middleware
// simulate some private data
var secrets = gin.H{
	"foo":    gin.H{"email": "foo@bar.com", "phone": "123433"},
	"austin": gin.H{"email": "austin@example.com", "phone": "666"},
	"lena":   gin.H{"email": "lena@guapa.com", "phone": "523443"},
}

func main() {
	r := gin.Default()

	// Group using gin.BasicAuth() middleware
	// gin.Accounts is a shortcut for map[string]string
	authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
		"foo":    "bar",
		"austin": "1234",
		"lena":   "hello2",
		"manu":   "4321",
	}))

	// /admin/secrets endpoint
	// hit "localhost:8080/admin/secrets
	authorized.GET("/secrets", func(c *gin.Context) {
		// get user, it was setted by the BasicAuth middleware
		user := c.MustGet(gin.AuthUserKey).(string)
		if secret, ok := secrets[user]; ok {
			c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
		} else {
			c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
		}
	})

	// Listen and server on 0.0.0.0:8080
	r.Run(":8080")
}
Goroutines inside a middleware

When starting inside a middleware or handler, you SHOULD NOT use the original context inside it, you have to use a read-only copy.

func main() {
	r := gin.Default()

	r.GET("/long_async", func(c *gin.Context) {
		// create copy to be used inside the goroutine
		c_cp := c.Copy()
		go func() {
			// simulate a long task with time.Sleep(). 5 seconds
			time.Sleep(5 * time.Second)

			// note than you are using the copied context "c_cp", IMPORTANT
			log.Println("Done! in path " + c_cp.Request.URL.Path)
		}()
	})


	r.GET("/long_sync", func(c *gin.Context) {
		// simulate a long task with time.Sleep(). 5 seconds
		time.Sleep(5 * time.Second)

		// since we are NOT using a goroutine, we do not have to copy the context
		log.Println("Done! in path " + c.Request.URL.Path)
	})

    // Listen and server on 0.0.0.0:8080
    r.Run(":8080")
}
Custom HTTP configuration

Use http.ListenAndServe() directly, like this:

func main() {
	router := gin.Default()
	http.ListenAndServe(":8080", router)
}

or

func main() {
	router := gin.Default()

	s := &http.Server{
		Addr:           ":8080",
		Handler:        router,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	s.ListenAndServe()
}

Documentation

Index

Constants

View Source
const (
	MIMEJSON              = binding.MIMEJSON
	MIMEHTML              = binding.MIMEHTML
	MIMEXML               = binding.MIMEXML
	MIMEXML2              = binding.MIMEXML2
	MIMEPlain             = binding.MIMEPlain
	MIMEPOSTForm          = binding.MIMEPOSTForm
	MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
)
View Source
const (
	DebugMode   string = "debug"
	ReleaseMode string = "release"
	TestMode    string = "test"
)
View Source
const AbortIndex int8 = math.MaxInt8 / 2
View Source
const (
	AuthUserKey = "user"
)
View Source
const BindKey = "_gin-gonic/gin/bindkey"
View Source
const ENV_GIN_MODE = "GIN_MODE"
View Source
const Version = "v1.0rc2"

Variables

View Source
var DefaultWriter io.Writer = colorable.NewColorableStdout()

Functions

func Dir

func Dir(root string, listDirectory bool) http.FileSystem

It returns a http.Filesystem that can be used by http.FileServer(). It is used interally in router.Static(). if listDirectory == true, then it works the same as http.Dir() otherwise it returns a filesystem that prevents http.FileServer() to list the directory files.

func DisableBindValidation

func DisableBindValidation()

func IsDebugging

func IsDebugging() bool

func Mode

func Mode() string

func SetMode

func SetMode(value string)

Types

type Accounts

type Accounts map[string]string

type Context

type Context struct {
	Request *http.Request
	Writer  ResponseWriter

	Params Params

	Keys     map[string]interface{}
	Errors   errorMsgs
	Accepted []string
	// contains filtered or unexported fields
}

Context is the most important part of gin. It allows us to pass variables between middleware, manage the flow, validate the JSON of a request and render a JSON response for example.

func (*Context) Abort

func (c *Context) Abort()

Stops the system to continue calling the pending handlers in the chain. Let's say you have an authorization middleware that validates if the request is authorized if the authorization fails (the password does not match). This method (Abort()) should be called in order to stop the execution of the actual handler.

func (*Context) AbortWithError

func (c *Context) AbortWithError(code int, err error) *Error

It calls AbortWithStatus() and Error() internally. This method stops the chain, writes the status code and pushes the specified error to `c.Errors`. See Context.Error() for more details.

func (*Context) AbortWithStatus

func (c *Context) AbortWithStatus(code int)

It calls Abort() and writes the headers with the specified status code. For example, a failed attempt to authentificate a request could use: context.AbortWithStatus(401).

func (*Context) Bind

func (c *Context) Bind(obj interface{}) error

This function checks the Content-Type to select a binding engine automatically, Depending the "Content-Type" header different bindings are used: "application/json" --> JSON binding "application/xml" --> XML binding else --> returns an error if Parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. It decodes the json payload into the struct specified as a pointer.Like ParseBody() but this method also writes a 400 error if the json is not valid.

func (*Context) BindJSON

func (c *Context) BindJSON(obj interface{}) error

Shortcut for c.BindWith(obj, binding.JSON)

func (*Context) BindWith

func (c *Context) BindWith(obj interface{}, b binding.Binding) error

func (*Context) ClientIP

func (c *Context) ClientIP() string

Best effort algoritm to return the real client IP, it parses X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.

func (*Context) ContentType

func (c *Context) ContentType() string

func (*Context) Copy

func (c *Context) Copy() *Context

func (*Context) Data

func (c *Context) Data(code int, contentType string, data []byte)

Writes some data into the body stream and updates the HTTP code.

func (*Context) Deadline

func (c *Context) Deadline() (deadline time.Time, ok bool)

func (*Context) DefaultPostForm

func (c *Context) DefaultPostForm(key, defaultValue string) string

func (*Context) DefaultQuery

func (c *Context) DefaultQuery(key, defaultValue string) string

func (*Context) Done

func (c *Context) Done() <-chan struct{}

func (*Context) Err

func (c *Context) Err() error

func (*Context) Error

func (c *Context) Error(err error) *Error

Attaches an error to the current context. The error is pushed to a list of errors. It's a good idea to call Error for each error that occurred during the resolution of a request. A middleware can be used to collect all the errors and push them to a database together, print a log, or append it in the HTTP response.

func (*Context) File

func (c *Context) File(filepath string)

Writes the specified file into the body stream in a efficient way.

func (*Context) Get

func (c *Context) Get(key string) (value interface{}, exists bool)

Returns the value for the given key, ie: (value, true). If the value does not exists it returns (nil, false)

func (*Context) HTML

func (c *Context) HTML(code int, name string, obj interface{})

Renders the HTTP template specified by its file name. It also updates the HTTP code and sets the Content-Type as "text/html". See http://golang.org/doc/articles/wiki/

func (*Context) Header

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

Intelligent shortcut for c.Writer.Header().Set(key, value) it writes a header in the response. If value == "", this method removes the header `c.Writer.Header().Del(key)`

func (*Context) IndentedJSON

func (c *Context) IndentedJSON(code int, obj interface{})

Serializes the given struct as pretty JSON (indented + endlines) into the response body. It also sets the Content-Type as "application/json". WARNING: we recommend to use this only for development propuses since printing pretty JSON is more CPU and bandwidth consuming. Use Context.JSON() instead.

func (*Context) IsAborted

func (c *Context) IsAborted() bool

Returns if the currect context was aborted.

func (*Context) JSON

func (c *Context) JSON(code int, obj interface{})

Serializes the given struct as JSON into the response body. It also sets the Content-Type as "application/json".

func (*Context) MustGet

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

Returns the value for the given key if it exists, otherwise it panics.

func (*Context) Negotiate

func (c *Context) Negotiate(code int, config Negotiate)

func (*Context) NegotiateFormat

func (c *Context) NegotiateFormat(offered ...string) string

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. See example in github.

func (*Context) Param

func (c *Context) Param(key string) string

Shortcut for c.Params.ByName(key)

func (*Context) PostForm

func (c *Context) PostForm(key string) (va string)

Shortcut for c.Request.PostFormValue(key)

func (*Context) Query

func (c *Context) Query(key string) (va string)

Shortcut for c.Request.URL.Query().Get(key)

func (*Context) Redirect

func (c *Context) Redirect(code int, location string)

Returns a HTTP redirect to the specific location.

func (*Context) Render

func (c *Context) Render(code int, r render.Render)

func (*Context) SSEvent

func (c *Context) SSEvent(name string, message interface{})

func (*Context) Set

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

Sets a new pair key/value just for this context. It also lazy initializes the hashmap if it was not used previously.

func (*Context) SetAccepted

func (c *Context) SetAccepted(formats ...string)

func (*Context) Stream

func (c *Context) Stream(step func(w io.Writer) bool)

func (*Context) String

func (c *Context) String(code int, format string, values ...interface{})

Writes the given string into the response body.

func (*Context) Value

func (c *Context) Value(key interface{}) interface{}

func (*Context) XML

func (c *Context) XML(code int, obj interface{})

Serializes the given struct as XML into the response body. It also sets the Content-Type as "application/xml".

type Engine

type Engine struct {
	RouterGroup
	HTMLRender render.HTMLRender

	// Enables automatic redirection if the current route can't be matched but a
	// handler for the path with (without) the trailing slash exists.
	// For example if /foo/ is requested but a route only exists for /foo, the
	// client is redirected to /foo with http status code 301 for GET requests
	// and 307 for all other request methods.
	RedirectTrailingSlash bool

	// If enabled, the router tries to fix the current request path, if no
	// handle is registered for it.
	// First superfluous path elements like ../ or // are removed.
	// Afterwards the router does a case-insensitive lookup of the cleaned path.
	// If a handle can be found for this route, the router makes a redirection
	// to the corrected path with status code 301 for GET requests and 307 for
	// all other request methods.
	// For example /FOO and /..//Foo could be redirected to /foo.
	// RedirectTrailingSlash is independent of this option.
	RedirectFixedPath bool

	// If enabled, the router checks if another method is allowed for the
	// current route, if the current request can not be routed.
	// If this is the case, the request is answered with 'Method Not Allowed'
	// and HTTP status code 405.
	// If no other Method is allowed, the request is delegated to the NotFound
	// handler.
	HandleMethodNotAllowed bool
	ForwardedByClientIP    bool
	// contains filtered or unexported fields
}

Represents the web framework, it wraps the blazing fast httprouter multiplexer and a list of global middlewares.

func Default

func Default() *Engine

Returns a Engine instance with the Logger and Recovery already attached.

func New

func New() *Engine

Returns a new blank Engine instance without any middleware attached. The most basic configuration

func (*Engine) LoadHTMLFiles

func (engine *Engine) LoadHTMLFiles(files ...string)

func (*Engine) LoadHTMLGlob

func (engine *Engine) LoadHTMLGlob(pattern string)

func (*Engine) NoMethod

func (engine *Engine) NoMethod(handlers ...HandlerFunc)

Sets the handlers called when... TODO

func (*Engine) NoRoute

func (engine *Engine) NoRoute(handlers ...HandlerFunc)

Adds handlers for NoRoute. It return a 404 code by default.

func (*Engine) Routes

func (engine *Engine) Routes() (routes RoutesInfo)

func (*Engine) Run

func (engine *Engine) Run(addr string) (err error)

The router is attached to a http.Server and starts listening and serving HTTP requests. It is a shortcut for http.ListenAndServe(addr, router) Note: this method will block the calling goroutine undefinitelly unless an error happens.

func (*Engine) RunTLS

func (engine *Engine) RunTLS(addr string, certFile string, keyFile string) (err error)

The router is attached to a http.Server and starts listening and serving HTTPS requests. It is a shortcut for http.ListenAndServeTLS(addr, certFile, keyFile, router) Note: this method will block the calling goroutine undefinitelly unless an error happens.

func (*Engine) RunUnix

func (engine *Engine) RunUnix(file string) (err error)

The router is attached to a http.Server and starts listening and serving HTTP requests through the specified unix socket (ie. a file) Note: this method will block the calling goroutine undefinitelly unless an error happens.

func (*Engine) ServeHTTP

func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request)

Conforms to the http.Handler interface.

func (*Engine) SetHTMLTemplate

func (engine *Engine) SetHTMLTemplate(templ *template.Template)

func (*Engine) Use

func (engine *Engine) Use(middlewares ...HandlerFunc) routesInterface

Attachs a global middleware to the router. ie. the middlewares attached though Use() will be included in the handlers chain for every single request. Even 404, 405, static files... For example, this is the right place for a logger or error management middleware.

type Error

type Error struct {
	Err  error
	Type ErrorType
	Meta interface{}
}

func (*Error) Error

func (msg *Error) Error() string

Implements the error interface

func (*Error) IsType

func (msg *Error) IsType(flags ErrorType) bool

func (*Error) JSON

func (msg *Error) JSON() interface{}

func (*Error) MarshalJSON

func (msg *Error) MarshalJSON() ([]byte, error)

Implements the json.Marshaller interface

func (*Error) SetMeta

func (msg *Error) SetMeta(data interface{}) *Error

func (*Error) SetType

func (msg *Error) SetType(flags ErrorType) *Error

type ErrorType

type ErrorType uint64
const (
	ErrorTypeBind    ErrorType = 1 << 63 // used when c.Bind() fails
	ErrorTypeRender  ErrorType = 1 << 62 // used when c.Render() fails
	ErrorTypePrivate ErrorType = 1 << 0
	ErrorTypePublic  ErrorType = 1 << 1

	ErrorTypeAny ErrorType = 1<<64 - 1
	ErrorTypeNu            = 2
)

type H

type H map[string]interface{}

func (H) MarshalXML

func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error

Allows type H to be used with xml.Marshal

type HandlerFunc

type HandlerFunc func(*Context)

func BasicAuth

func BasicAuth(accounts Accounts) HandlerFunc

Implements a basic Basic HTTP Authorization. It takes as argument a map[string]string where the key is the user name and the value is the password.

func BasicAuthForRealm

func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc

Implements a basic Basic HTTP Authorization. It takes as arguments a map[string]string where the key is the user name and the value is the password, as well as the name of the Realm (see http://tools.ietf.org/html/rfc2617#section-1.2)

func Bind

func Bind(val interface{}) HandlerFunc

func ErrorLogger

func ErrorLogger() HandlerFunc

func ErrorLoggerT

func ErrorLoggerT(typ ErrorType) HandlerFunc

func Logger

func Logger() HandlerFunc

Instances a Logger middleware that will write the logs to gin.DefaultWriter By default gin.DefaultWriter = os.Stdout

func LoggerWithWriter

func LoggerWithWriter(out io.Writer) HandlerFunc

Instance a Logger middleware with the specified writter buffer. Example: os.Stdout, a file opened in write mode, a socket...

func Recovery

func Recovery() HandlerFunc

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

func RecoveryWithWriter

func RecoveryWithWriter(out io.Writer) HandlerFunc

func WrapF

func WrapF(f http.HandlerFunc) HandlerFunc

func WrapH

func WrapH(h http.Handler) HandlerFunc

type HandlersChain

type HandlersChain []HandlerFunc

func (HandlersChain) Last

func (c HandlersChain) Last() HandlerFunc

type Negotiate

type Negotiate struct {
	Offered  []string
	HTMLName string
	HTMLData interface{}
	JSONData interface{}
	XMLData  interface{}
	Data     interface{}
}

type Param

type Param struct {
	Key   string
	Value string
}

Param is a single URL parameter, consisting of a key and a value.

type Params

type Params []Param

Params is a Param-slice, as returned by the router. The slice is ordered, the first URL parameter is also the first slice value. It is therefore safe to read values by the index.

func (Params) ByName

func (ps Params) ByName(name string) (va string)

func (Params) Get

func (ps Params) Get(name string) (string, bool)

ByName returns the value of the first Param which key matches the given name. If no matching Param is found, an empty string is returned.

type ResponseWriter

type ResponseWriter interface {
	http.ResponseWriter
	http.Hijacker
	http.Flusher
	http.CloseNotifier

	Status() int
	Size() int
	WriteString(string) (int, error)
	Written() bool
	WriteHeaderNow()
}

type RouteInfo

type RouteInfo struct {
	Method  string
	Path    string
	Handler string
}

type RouterGroup

type RouterGroup struct {
	Handlers HandlersChain
	BasePath string
	// contains filtered or unexported fields
}

Used internally to configure router, a RouterGroup is associated with a prefix and an array of handlers (middlewares)

func (*RouterGroup) Any

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

func (*RouterGroup) DELETE

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

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

func (*RouterGroup) GET

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

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

func (*RouterGroup) Group

func (group *RouterGroup) Group(relativePath string, 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 (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) routesInterface

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

func (*RouterGroup) Handle

func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc) routesInterface

func (*RouterGroup) OPTIONS

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

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

func (*RouterGroup) PATCH

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

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

func (*RouterGroup) POST

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

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

func (*RouterGroup) PUT

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

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

func (*RouterGroup) Static

func (group *RouterGroup) Static(relativePath, root string) routesInterface

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

func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) routesInterface

func (*RouterGroup) StaticFile

func (group *RouterGroup) StaticFile(relativePath, filepath string) routesInterface

func (*RouterGroup) Use

func (group *RouterGroup) Use(middlewares ...HandlerFunc) routesInterface

Adds middlewares to the group, see example code in github.

type RoutesInfo

type RoutesInfo []RouteInfo

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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