Documentation ¶
Overview ¶
Example ¶
package main import ( "fmt" "github.com/teambition/gear" "github.com/teambition/gear/logging" "github.com/teambition/gear/middleware/static" ) func main() { // Create app app := gear.New() // Use a default logger middleware app.UseHandler(logging.Default()) // Add a static middleware // http://localhost:3000/middleware/static.go app.Use(static.New(static.Options{ Root: "./middleware", Prefix: "/middleware", StripPrefix: true, })) // Add some middleware to app app.Use(func(ctx *gear.Context) (err error) { // fmt.Println(ctx.IP(), ctx.Method, ctx.Path // Do something... // Add after hook to the ctx ctx.After(func() { // Do something in after hook fmt.Println("After hook") }) return }) // Create views router ViewRouter := gear.NewRouter() // "http://localhost:3000" ViewRouter.Get("/", func(ctx *gear.Context) error { return ctx.HTML(200, "<h1>Hello, Gear!</h1>") }) // "http://localhost:3000/view/abc" // "http://localhost:3000/view/123" ViewRouter.Get("/view/:view", func(ctx *gear.Context) error { view := ctx.Param("view") if view == "" { return gear.ErrBadRequest.WithMsg("Invalid view") } return ctx.HTML(200, "View: "+view) }) // "http://localhost:3000/abc" // "http://localhost:3000/abc/efg" ViewRouter.Get("/:others*", func(ctx *gear.Context) error { others := ctx.Param("others") if others == "" { return gear.ErrBadRequest.WithMsg("Invalid path") } return ctx.HTML(200, "Request path: /"+others) }) // Create API router APIRouter := gear.NewRouter(gear.RouterOptions{Root: "/api", IgnoreCase: true}) // "http://localhost:3000/api/user/abc" // "http://localhost:3000/abc/user/123" APIRouter.Get("/user/:id", func(ctx *gear.Context) error { id := ctx.Param("id") if id == "" { return gear.ErrBadRequest.WithMsg("Invalid user id") } return ctx.JSON(200, map[string]string{ "Method": ctx.Method, "Path": ctx.Path, "UserID": id, }) }) // Must add APIRouter first. app.UseHandler(APIRouter) app.UseHandler(ViewRouter) // Start app at 3000 app.Error(app.Listen(":3000")) }
Output:
Index ¶
- Constants
- Variables
- func ContentDisposition(fileName, dispositionType string) (header string)
- func IsNil(val interface{}) bool
- func IsStatusCode(status int) bool
- func ValuesToStruct(values map[string][]string, target interface{}, tag string) (err error)
- type Any
- type App
- func (app *App) Close(ctx ...context.Context) error
- func (app *App) Env() string
- func (app *App) Error(err error)
- func (app *App) Listen(addr string) error
- func (app *App) ListenTLS(addr, certFile, keyFile string) error
- func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (app *App) Set(key, val interface{})
- func (app *App) Start(addr ...string) *ServerListener
- func (app *App) Use(handle Middleware)
- func (app *App) UseHandler(h Handler)
- type BodyParser
- type BodyTemplate
- type Compressible
- type Context
- func (ctx *Context) AcceptCharset(preferred ...string) string
- func (ctx *Context) AcceptEncoding(preferred ...string) string
- func (ctx *Context) AcceptLanguage(preferred ...string) string
- func (ctx *Context) AcceptType(preferred ...string) string
- func (ctx *Context) After(hook func())
- func (ctx *Context) Any(any interface{}) (val interface{}, err error)
- func (ctx *Context) Attachment(name string, modtime time.Time, content io.ReadSeeker, inline ...bool) (err error)
- func (ctx *Context) Cancel()
- func (ctx *Context) Context() context.Context
- func (ctx *Context) Deadline() (time.Time, bool)
- func (ctx *Context) Done() <-chan struct{}
- func (ctx *Context) End(code int, buf ...[]byte) (err error)
- func (ctx *Context) Err() error
- func (ctx *Context) Error(e error) error
- func (ctx *Context) ErrorStatus(status int) error
- func (ctx *Context) Get(key string) string
- func (ctx *Context) HTML(code int, str string) error
- func (ctx *Context) IP() net.IP
- func (ctx *Context) JSON(code int, val interface{}) error
- func (ctx *Context) JSONBlob(code int, buf []byte) error
- func (ctx *Context) JSONP(code int, callback string, val interface{}) error
- func (ctx *Context) JSONPBlob(code int, callback string, buf []byte) error
- func (ctx *Context) OnEnd(hook func())
- func (ctx *Context) Param(key string) (val string)
- func (ctx *Context) ParseBody(body BodyTemplate) error
- func (ctx *Context) ParseURL(body BodyTemplate) error
- func (ctx *Context) Protocol() string
- func (ctx *Context) Query(name string) string
- func (ctx *Context) QueryAll(name string) []string
- func (ctx *Context) Redirect(url string) (err error)
- func (ctx *Context) Render(code int, name string, data interface{}) (err error)
- func (ctx *Context) Set(key, value string)
- func (ctx *Context) SetAny(key, val interface{})
- func (ctx *Context) Setting(key interface{}) interface{}
- func (ctx *Context) Status(code int)
- func (ctx *Context) Stream(code int, contentType string, r io.Reader) (err error)
- func (ctx *Context) Timing(dt time.Duration, fn func(context.Context)) (err error)
- func (ctx *Context) Type(str string)
- func (ctx *Context) Value(key interface{}) (val interface{})
- func (ctx *Context) WithCancel() (context.Context, context.CancelFunc)
- func (ctx *Context) WithContext(c context.Context)
- func (ctx *Context) WithDeadline(deadline time.Time) (context.Context, context.CancelFunc)
- func (ctx *Context) WithTimeout(timeout time.Duration) (context.Context, context.CancelFunc)
- func (ctx *Context) WithValue(key, val interface{}) context.Context
- func (ctx *Context) XML(code int, val interface{}) error
- func (ctx *Context) XMLBlob(code int, buf []byte) error
- type DefaultBodyParser
- type DefaultCompress
- type DefaultURLParser
- type Error
- func (err *Error) Error() string
- func (err Error) From(e error) *Error
- func (err Error) GoString() string
- func (err *Error) Status() int
- func (err Error) String() string
- func (err Error) WithCode(code int) *Error
- func (err Error) WithMsg(msgs ...string) *Error
- func (err Error) WithMsgf(format string, args ...interface{}) *Error
- func (err Error) WithStack(skip ...int) *Error
- type HTTPError
- type Handler
- type LoggerFilterWriter
- type Middleware
- type Renderer
- type Response
- func (r *Response) Body() []byte
- func (r *Response) CloseNotify() <-chan bool
- func (r *Response) Del(key string)
- func (r *Response) Flush()
- func (r *Response) Get(key string) string
- func (r *Response) Header() http.Header
- func (r *Response) HeaderWrote() bool
- func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error)
- func (r *Response) Push(target string, opts *http.PushOptions) error
- func (r *Response) ResetHeader(filterReg ...*regexp.Regexp)
- func (r *Response) Set(key, value string)
- func (r *Response) Status() int
- func (r *Response) Type() string
- func (r *Response) Vary(field string)
- func (r *Response) Write(buf []byte) (int, error)
- func (r *Response) WriteHeader(code int)
- type Router
- func (r *Router) Delete(pattern string, handlers ...Middleware)
- func (r *Router) Get(pattern string, handlers ...Middleware)
- func (r *Router) Handle(method, pattern string, handlers ...Middleware)
- func (r *Router) Head(pattern string, handlers ...Middleware)
- func (r *Router) Options(pattern string, handlers ...Middleware)
- func (r *Router) Otherwise(handlers ...Middleware)
- func (r *Router) Patch(pattern string, handlers ...Middleware)
- func (r *Router) Post(pattern string, handlers ...Middleware)
- func (r *Router) Put(pattern string, handlers ...Middleware)
- func (r *Router) Serve(ctx *Context) error
- func (r *Router) Use(handle Middleware)
- type RouterOptions
- type ServerListener
- type URLParser
Examples ¶
Constants ¶
const ( // It will be used by `ctx.ParseBody`, value should implements `gear.BodyParser` interface, default to: // app.Set(gear.SetBodyParser, gear.DefaultBodyParser(1<<20)) SetBodyParser appSetting = iota // It will be used by `ctx.ParseURL`, value should implements `gear.URLParser` interface, default to: // app.Set(gear.SetURLParser, gear.DefaultURLParser) SetURLParser // Enable compress for response, value should implements `gear.Compressible` interface, no default value. // Example: // import "github.com/teambition/compressible-go" // // app := gear.New() // app.Set(gear.SetCompress, compressible.WithThreshold(1024)) SetCompress // Set secret keys for signed cookies, it will be used by `ctx.Cookies`, value should be `[]string` type, // no default value. More document https://github.com/go-http-utils/cookie, Example: // app.Set(gear.SetKeys, []string{"some key2", "some key1"}) SetKeys // Set a logger to app, value should be `*log.Logger` instance, default to: // app.Set(gear.SetLogger, log.New(os.Stderr, "", log.LstdFlags)) // Maybe you need LoggerFilterWriter to filter some server errors in production: // app.Set(gear.SetLogger, log.New(gear.DefaultFilterWriter(), "", log.LstdFlags)) SetLogger // Set a on-error hook to app, value should be `func(ctx *Context, err *Error)`, no default value. SetOnError // Set a renderer to app, it will be used by `ctx.Render`, value should implements `gear.Renderer` interface, // no default value. SetRenderer // Set a timeout to for the middleware process, value should be `time.Duration`. No default. // Example: // app.Set(gear.SetTimeout, 3*time.Second) SetTimeout // Set a function that Wrap the gear.Context' underlayer context.Context. No default. SetWithContext // Set a app env string to app, it can be retrieved by `ctx.Setting(gear.SetEnv)`. // Default to os process "APP_ENV" or "development". SetEnv // Set a server name that respond to client as "Server" header. // Default to "Gear/{version}". SetServerName )
Build-in app settings
const ( // Got from https://github.com/labstack/echo MIMEApplicationJSON = "application/json" MIMEApplicationJSONCharsetUTF8 = "application/json; charset=utf-8" MIMEApplicationJavaScript = "application/javascript" MIMEApplicationJavaScriptCharsetUTF8 = "application/javascript; charset=utf-8" MIMEApplicationXML = "application/xml" MIMEApplicationXMLCharsetUTF8 = "application/xml; charset=utf-8" MIMEApplicationForm = "application/x-www-form-urlencoded" MIMEApplicationProtobuf = "application/protobuf" MIMEApplicationMsgpack = "application/msgpack" MIMETextHTML = "text/html" MIMETextHTMLCharsetUTF8 = "text/html; charset=utf-8" MIMETextPlain = "text/plain" MIMETextPlainCharsetUTF8 = "text/plain; charset=utf-8" MIMEMultipartForm = "multipart/form-data" MIMEOctetStream = "application/octet-stream" )
MIME types
const ( HeaderAccept = "Accept" // Requests, Responses HeaderAcceptCharset = "Accept-Charset" // Requests HeaderAcceptEncoding = "Accept-Encoding" // Requests HeaderAcceptLanguage = "Accept-Language" // Requests HeaderAuthorization = "Authorization" // Requests HeaderCacheControl = "Cache-Control" // Requests, Responses HeaderContentLength = "Content-Length" // Requests, Responses HeaderContentMD5 = "Content-MD5" // Requests, Responses HeaderContentType = "Content-Type" // Requests, Responses HeaderIfMatch = "If-Match" // Requests HeaderIfModifiedSince = "If-Modified-Since" // Requests HeaderIfNoneMatch = "If-None-Match" // Requests HeaderIfRange = "If-Range" // Requests HeaderIfUnmodifiedSince = "If-Unmodified-Since" // Requests HeaderMaxForwards = "Max-Forwards" // Requests HeaderProxyAuthorization = "Proxy-Authorization" // Requests HeaderPragma = "Pragma" // Requests, Responses HeaderRange = "Range" // Requests HeaderReferer = "Referer" // Requests HeaderUserAgent = "User-Agent" // Requests HeaderTE = "TE" // Requests HeaderVia = "Via" // Requests HeaderWarning = "Warning" // Requests, Responses HeaderCookie = "Cookie" // Requests HeaderOrigin = "Origin" // Requests HeaderAcceptDatetime = "Accept-Datetime" // Requests HeaderXRequestedWith = "X-Requested-With" // Requests HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" // Responses HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" // Responses HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" // Responses HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" // Responses HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" // Responses HeaderAccessControlMaxAge = "Access-Control-Max-Age" // Responses HeaderAccessControlRequestMethod = "Access-Control-Request-Method" // Responses HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" // Responses HeaderAcceptPatch = "Accept-Patch" // Responses HeaderAcceptRanges = "Accept-Ranges" // Responses HeaderAllow = "Allow" // Responses HeaderContentEncoding = "Content-Encoding" // Responses HeaderContentLanguage = "Content-Language" // Responses HeaderContentLocation = "Content-Location" // Responses HeaderContentDisposition = "Content-Disposition" // Responses HeaderContentRange = "Content-Range" // Responses HeaderETag = "ETag" // Responses HeaderExpires = "Expires" // Responses HeaderLastModified = "Last-Modified" // Responses HeaderLink = "Link" // Responses HeaderLocation = "Location" // Responses HeaderP3P = "P3P" // Responses HeaderProxyAuthenticate = "Proxy-Authenticate" // Responses HeaderRefresh = "Refresh" // Responses HeaderRetryAfter = "Retry-After" // Responses HeaderServer = "Server" // Responses HeaderSetCookie = "Set-Cookie" // Responses HeaderStrictTransportSecurity = "Strict-Transport-Security" // Responses HeaderTransferEncoding = "Transfer-Encoding" // Responses HeaderUpgrade = "Upgrade" // Responses HeaderVary = "Vary" // Responses HeaderWWWAuthenticate = "WWW-Authenticate" // Responses HeaderPublicKeyPins = "Public-Key-Pins" // Responses HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only" // Responses HeaderRefererPolicy = "Referrer-Policy" // Responses // Common Non-Standard Response Headers HeaderXFrameOptions = "X-Frame-Options" // Responses HeaderXXSSProtection = "X-XSS-Protection" // Responses HeaderContentSecurityPolicy = "Content-Security-Policy" // Responses HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" // Responses HeaderXContentSecurityPolicy = "X-Content-Security-Policy" // Responses HeaderXWebKitCSP = "X-WebKit-CSP" // Responses HeaderXContentTypeOptions = "X-Content-Type-Options" // Responses HeaderXPoweredBy = "X-Powered-By" // Responses HeaderXUACompatible = "X-UA-Compatible" // Responses HeaderXForwardedProto = "X-Forwarded-Proto" // Responses HeaderXHTTPMethodOverride = "X-HTTP-Method-Override" // Responses HeaderXForwardedFor = "X-Forwarded-For" // Responses HeaderXRealIP = "X-Real-IP" // Responses HeaderXCSRFToken = "X-CSRF-Token" // Responses HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" // Responses HeaderXDownloadOptions = "X-Download-Options" // Responses )
HTTP Header Fields
const Version = "1.7.6"
Version is Gear's version
Variables ¶
var ( Err = &Error{Code: http.StatusInternalServerError, Err: "Error"} // https://golang.org/pkg/net/http/#pkg-constants ErrBadRequest = Err.WithCode(http.StatusBadRequest) ErrPaymentRequired = Err.WithCode(http.StatusPaymentRequired) ErrForbidden = Err.WithCode(http.StatusForbidden) ErrNotFound = Err.WithCode(http.StatusNotFound) ErrMethodNotAllowed = Err.WithCode(http.StatusMethodNotAllowed) ErrNotAcceptable = Err.WithCode(http.StatusNotAcceptable) ErrProxyAuthRequired = Err.WithCode(http.StatusProxyAuthRequired) ErrRequestTimeout = Err.WithCode(http.StatusRequestTimeout) ErrConflict = Err.WithCode(http.StatusConflict) ErrGone = Err.WithCode(http.StatusGone) ErrLengthRequired = Err.WithCode(http.StatusLengthRequired) ErrPreconditionFailed = Err.WithCode(http.StatusPreconditionFailed) ErrRequestEntityTooLarge = Err.WithCode(http.StatusRequestEntityTooLarge) ErrRequestURITooLong = Err.WithCode(http.StatusRequestURITooLong) ErrUnsupportedMediaType = Err.WithCode(http.StatusUnsupportedMediaType) ErrRequestedRangeNotSatisfiable = Err.WithCode(http.StatusRequestedRangeNotSatisfiable) ErrExpectationFailed = Err.WithCode(http.StatusExpectationFailed) ErrTeapot = Err.WithCode(http.StatusTeapot) ErrUnprocessableEntity = Err.WithCode(http.StatusUnprocessableEntity) ErrLocked = Err.WithCode(http.StatusLocked) ErrFailedDependency = Err.WithCode(http.StatusFailedDependency) ErrUpgradeRequired = Err.WithCode(http.StatusUpgradeRequired) ErrPreconditionRequired = Err.WithCode(http.StatusPreconditionRequired) ErrTooManyRequests = Err.WithCode(http.StatusTooManyRequests) ErrRequestHeaderFieldsTooLarge = Err.WithCode(http.StatusRequestHeaderFieldsTooLarge) ErrInternalServerError = Err.WithCode(http.StatusInternalServerError) ErrNotImplemented = Err.WithCode(http.StatusNotImplemented) ErrBadGateway = Err.WithCode(http.StatusBadGateway) ErrGatewayTimeout = Err.WithCode(http.StatusGatewayTimeout) ErrHTTPVersionNotSupported = Err.WithCode(http.StatusHTTPVersionNotSupported) ErrVariantAlsoNegotiates = Err.WithCode(http.StatusVariantAlsoNegotiates) ErrInsufficientStorage = Err.WithCode(http.StatusInsufficientStorage) ErrLoopDetected = Err.WithCode(http.StatusLoopDetected) ErrNotExtended = Err.WithCode(http.StatusNotExtended) ErrNetworkAuthenticationRequired = Err.WithCode(http.StatusNetworkAuthenticationRequired) )
Predefined errors
Functions ¶
func ContentDisposition ¶ added in v1.0.1
ContentDisposition implements a simple version of https://tools.ietf.org/html/rfc2183 Use mime.ParseMediaType to parse Content-Disposition header.
func IsNil ¶ added in v0.26.4
func IsNil(val interface{}) bool
IsNil checks if a specified object is nil or not, without Failing.
func IsStatusCode ¶ added in v0.18.0
IsStatusCode returns true if status is HTTP status code. https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
func ValuesToStruct ¶ added in v1.5.0
ValuesToStruct converts url.Values into struct object.
type jsonQueryTemplate struct { ID string `json:"id" form:"id"` Pass string `json:"pass" form:"pass"` } target := jsonQueryTemplate{} ValuesToStruct(map[string][]string{ "id": []string{"some id"}, "pass": []string{"some pass"}, }, &target, "form")
Types ¶
type App ¶ added in v0.11.0
App is the top-level framework app instance.
Hello Gear!
package main import "github.com/teambition/gear" func main() { app := gear.New() // Create app app.Use(func(ctx *gear.Context) error { return ctx.HTML(200, "<h1>Hello, Gear!</h1>") }) app.Error(app.Listen(":3000")) }
func (*App) Close ¶ added in v1.0.0
Close closes the underlying server. If context omit, Server.Close will be used to close immediately. Otherwise Server.Shutdown will be used to close gracefully.
func (*App) Env ¶ added in v0.26.4
Env returns app' env. You can set app env with `app.Set(gear.SetEnv, "dome env")` Default to os process "APP_ENV" or "development".
func (*App) ServeHTTP ¶ added in v0.25.0
func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request)
func (*App) Set ¶ added in v0.12.0
func (app *App) Set(key, val interface{})
Set add key/value settings to app. The settings can be retrieved by `ctx.Setting(key)`.
func (*App) Start ¶ added in v0.11.0
func (app *App) Start(addr ...string) *ServerListener
Start starts a non-blocking app instance. It is useful for testing. If addr omit, the app will listen on a random addr, use ServerListener.Addr() to get it. The non-blocking app instance must close by ServerListener.Close().
func (*App) Use ¶ added in v0.11.0
func (app *App) Use(handle Middleware)
Use uses the given middleware `handle`.
func (*App) UseHandler ¶ added in v0.11.0
UseHandler uses a instance that implemented Handler interface.
type BodyParser ¶ added in v0.23.0
type BodyParser interface { // Maximum allowed size for a request body MaxBytes() int64 Parse(buf []byte, body interface{}, mediaType, charset string) error }
BodyParser interface is used by ctx.ParseBody. Default to:
app.Set(gear.SetBodyParser, DefaultBodyParser(1<<20))
type BodyTemplate ¶ added in v0.23.0
type BodyTemplate interface {
Validate() error
}
BodyTemplate interface is used by ctx.ParseBody.
type Compressible ¶ added in v0.16.5
type Compressible interface { // Compressible checks the response Content-Type and Content-Length to // determine whether to compress. // `length == 0` means response body maybe stream, or will be writed later. Compressible(contentType string, contentLength int) bool }
Compressible interface is use to enable compress response content.
type Context ¶
type Context struct { Req *http.Request Res *Response Cookies *cookie.Cookies // https://github.com/go-http-utils/cookie Host string Method string Path string // contains filtered or unexported fields }
Context represents the context of the current HTTP request. It holds request and response objects, path, path parameters, data, registered handler and content.Context.
func NewContext ¶ added in v0.5.0
NewContext creates an instance of Context. Export for testing middleware.
func (*Context) AcceptCharset ¶ added in v0.21.0
AcceptCharset returns the most preferred charset from the HTTP Accept-Charset header. If nothing accepted, then empty string is returned.
func (*Context) AcceptEncoding ¶ added in v0.21.0
AcceptEncoding returns the most preferred encoding from the HTTP Accept-Encoding header. If nothing accepted, then empty string is returned.
func (*Context) AcceptLanguage ¶ added in v0.21.0
AcceptLanguage returns the most preferred language from the HTTP Accept-Language header. If nothing accepted, then empty string is returned.
func (*Context) AcceptType ¶ added in v0.21.0
AcceptType returns the most preferred content type from the HTTP Accept header. If nothing accepted, then empty string is returned.
func (*Context) After ¶
func (ctx *Context) After(hook func())
After add a "after hook" to the ctx that will run after middleware process, but before Response.WriteHeader.
func (*Context) Any ¶ added in v0.10.0
Any returns the value on this ctx by key. If key is instance of Any and value not set, any.New will be called to eval the value, and then set to the ctx. if any.New returns error, the value will not be set.
// create some Any type for your project. type someAnyType struct{} type someAnyResult struct { r *http.Request } var someAnyKey = &someAnyType{} func (t *someAnyType) New(ctx *gear.Context) (interface{}, error) { return &someAnyResult{r: ctx.Req}, nil } // use it in app if val, err := ctx.Any(someAnyKey); err == nil { res := val.(*someAnyResult) }
func (*Context) Attachment ¶
func (ctx *Context) Attachment(name string, modtime time.Time, content io.ReadSeeker, inline ...bool) (err error)
Attachment sends a response from `io.ReaderSeeker` as attachment, prompting client to save the file. If inline is true, the attachment will sends as inline, opening the file in the browser. It will end the ctx. The middlewares after current middleware will not run. "after hooks" and "end hooks" will run normally.
func (*Context) Cancel ¶
func (ctx *Context) Cancel()
Cancel cancel the ctx and all it' children context. The ctx' process will ended too.
func (*Context) Deadline ¶ added in v0.5.0
Deadline returns the time when work done on behalf of this context should be canceled.
func (*Context) Done ¶ added in v0.5.0
func (ctx *Context) Done() <-chan struct{}
Done returns a channel that's closed when work done on behalf of this context should be canceled.
func (*Context) End ¶
End end the ctx with bytes and status code optionally. After it's called, the rest of middleware handles will not run. But "after hooks" and "end hooks" will run normally.
func (*Context) Error ¶
Error send a error with application/json type to response. It will not reset response headers and not use app.OnError hook It will end the ctx. The middlewares after current middleware and "after hooks" will not run. "end hooks" will run normally.
func (*Context) ErrorStatus ¶ added in v0.23.0
ErrorStatus send a error by status code with application/json type to response. The status should be 4xx or 5xx code. It will not reset response headers and not use app.OnError hook It will end the ctx. The middlewares after current middleware and "after hooks" will not run. "end hooks" will run normally.
func (*Context) HTML ¶
HTML set an Html body with status code to response. It will end the ctx. The middlewares after current middleware will not run. "after hooks" and "end hooks" will run normally.
func (*Context) IP ¶
IP returns the client's network address based on `X-Forwarded-For` or `X-Real-IP` request header.
func (*Context) JSON ¶
JSON set a JSON body with status code to response. It will end the ctx. The middlewares after current middleware will not run. "after hooks" (if no error) and "end hooks" will run normally.
func (*Context) JSONBlob ¶
JSONBlob set a JSON blob body with status code to response. It will end the ctx. The middlewares after current middleware will not run. "after hooks" and "end hooks" will run normally.
func (*Context) JSONP ¶
JSONP sends a JSONP response with status code. It uses `callback` to construct the JSONP payload. It will end the ctx. The middlewares after current middleware will not run. "after hooks" (if no error) and "end hooks" will run normally.
func (*Context) JSONPBlob ¶
JSONPBlob sends a JSONP blob response with status code. It uses `callback` to construct the JSONP payload. It will end the ctx. The middlewares after current middleware will not run. "after hooks" and "end hooks" will run normally.
func (*Context) OnEnd ¶
func (ctx *Context) OnEnd(hook func())
OnEnd add a "end hook" to the ctx that will run after Response.WriteHeader. Take care that http.ResponseWriter and http.Request maybe reset for reusing. Issue https://github.com/teambition/gear/issues/24
func (*Context) ParseBody ¶ added in v0.23.0
func (ctx *Context) ParseBody(body BodyTemplate) error
ParseBody parses request content with BodyParser, stores the result in the value pointed to by BodyTemplate body, and validate it. DefaultBodyParser support JSON, Form and XML.
Define a BodyTemplate type in some API:
type jsonBodyTemplate struct { ID string `json:"id" form:"id"` Pass string `json:"pass" form:"pass"` } func (b *jsonBodyTemplate) Validate() error { if len(b.ID) < 3 || len(b.Pass) < 6 { return ErrBadRequest.WithMsg("invalid id or pass") } return nil }
Use it in middleware:
body := jsonBodyTemplate{} if err := ctx.ParseBody(&body) { return err }
func (*Context) ParseURL ¶ added in v1.5.0
func (ctx *Context) ParseURL(body BodyTemplate) error
ParseURL parses router params (like ctx.Param) and queries (like ctx.Query) in request URL, stores the result in the struct object pointed to by BodyTemplate body, and validate it.
Define a BodyTemplate type in some API:
type taskTemplate struct { ID bson.ObjectId `json:"_taskID" param:"_taskID"` // router.Get("/tasks/:_taskID", APIhandler) StartAt time.Time `json:"startAt" query:"startAt"` // GET /tasks/50c32afae8cf1439d35a87e6?startAt=2017-05-03T10:06:45.319Z } func (b *taskTemplate) Validate() error { if !b.ID.Valid() { return gear.ErrBadRequest.WithMsg("invalid task id") } if b.StartAt.IsZero() { return gear.ErrBadRequest.WithMsg("invalid task start time") } return nil }
Use it in APIhandler:
body := taskTemplate{} if err := ctx.ParseURL(&body) { return err }
func (*Context) Protocol ¶ added in v1.4.2
Protocol returns the protocol ("http" or "https") that a client used to connect to your proxy or load balancer. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
func (*Context) QueryAll ¶ added in v0.23.2
QueryAll returns all query params for the provided name.
func (*Context) Redirect ¶
Redirect redirects the request with status code 302. You can use other status code with ctx.Status method, It is a wrap of http.Redirect. It will end the ctx. The middlewares after current middleware will not run. "after hooks" and "end hooks" will run normally.
func (*Context) Render ¶
Render renders a template with data and sends a text/html response with status code. Templates can be registered using `app.Renderer = Renderer`. It will end the ctx. The middlewares after current middleware will not run. "after hooks" (if no error) and "end hooks" will run normally.
func (*Context) SetAny ¶ added in v0.10.0
func (ctx *Context) SetAny(key, val interface{})
SetAny save a key, value pair on the ctx. Then we can use ctx.Any(key) to retrieve the value from ctx.
func (*Context) Setting ¶ added in v0.12.0
func (ctx *Context) Setting(key interface{}) interface{}
Setting returns App's settings by key
fmt.Println(ctx.Setting(gear.SetEnv).(string) == "development") app.Set(gear.SetEnv, "production") fmt.Println(ctx.Setting(gear.SetEnv).(string) == "production")
func (*Context) Status ¶
Status set a status code to the response, ctx.Res.Status() returns the status code.
func (*Context) Stream ¶
Stream sends a streaming response with status code and content type. It will end the ctx. The middlewares after current middleware will not run. "after hooks" and "end hooks" will run normally.
func (*Context) Timing ¶ added in v0.16.1
Timing runs fn with the given time limit. If a call runs for longer than its time limit or panic, it will return context.DeadlineExceeded error or panic error.
func (*Context) Type ¶
Type set a content type to the response, ctx.Res.Type() returns the content type.
func (*Context) Value ¶ added in v0.5.0
func (ctx *Context) Value(key interface{}) (val interface{})
Value returns the value associated with this context for key, or nil if no value is associated with key. Successive calls to Value with the same key returns the same result.
func (*Context) WithCancel ¶
func (ctx *Context) WithCancel() (context.Context, context.CancelFunc)
WithCancel returns a copy of the ctx with a new Done channel. The returned context's Done channel is closed when the returned cancel function is called or when the parent context's Done channel is closed, whichever happens first.
func (*Context) WithContext ¶ added in v0.26.6
WithContext sets the context to underlying gear.Context. The context must be a children or a grandchild of gear.Context.
ctx.WithContext(ctx.WithValue("key", "value")) // ctx.Value("key") == "value"
a opentracing middleware:
func New(opts ...opentracing.StartSpanOption) gear.Middleware { return func(ctx *gear.Context) error { span := opentracing.StartSpan(fmt.Sprintf(`%s %s`, ctx.Method, ctx.Path), opts...) ctx.WithContext(opentracing.ContextWithSpan(ctx.Context(), span)) ctx.OnEnd(span.Finish) return nil } }
func (*Context) WithDeadline ¶
WithDeadline returns a copy of the ctx with the deadline adjusted to be no later than d.
func (*Context) WithTimeout ¶
WithTimeout returns WithDeadline(time.Now().Add(timeout)).
func (*Context) WithValue ¶
WithValue returns a copy of the ctx in which the value associated with key is val.
type DefaultBodyParser ¶ added in v0.23.0
type DefaultBodyParser int64
DefaultBodyParser is default BodyParser type. SetBodyParser used 1MB as default:
app.Set(gear.SetBodyParser, DefaultBodyParser(1<<20))
func (DefaultBodyParser) MaxBytes ¶ added in v0.23.0
func (d DefaultBodyParser) MaxBytes() int64
MaxBytes implemented BodyParser interface.
type DefaultCompress ¶ added in v0.14.0
type DefaultCompress struct{}
DefaultCompress is defalut Compress implemented. Use it to enable compress:
app.Set(gear.SetCompress, &gear.DefaultCompress{})
func (*DefaultCompress) Compressible ¶ added in v0.14.0
func (d *DefaultCompress) Compressible(contentType string, contentLength int) bool
Compressible implemented Compress interface. Recommend https://github.com/teambition/compressible-go.
import "github.com/teambition/compressible-go" app := gear.New() app.Set(gear.SetCompress, compressible.WithThreshold(1024)) // Add a static middleware app.Use(static.New(static.Options{ Root: "./", Prefix: "/", })) app.Error(app.Listen(":3000")) // http://127.0.0.1:3000/
type DefaultURLParser ¶ added in v1.5.0
type DefaultURLParser struct{}
DefaultURLParser is default URLParser type.
type Error ¶ added in v0.3.0
type Error struct { Code int `json:"-"` Err string `json:"error"` Msg string `json:"message"` Data interface{} `json:"data,omitempty"` Stack string `json:"-"` }
Error represents a numeric error with optional meta. It can be used in middleware as a return result.
func ErrorWithStack ¶ added in v0.24.0
ErrorWithStack create a error with stacktrace
func (Error) From ¶ added in v1.4.0
From returns a copy of err with given error. It will try to merge the given error. If the given error is a *Error instance, it will be returned without copy.
err := gear.ErrBadRequest.From(errors.New("invalid email")) err := gear.Err.From(someErr)
func (Error) GoString ¶ added in v1.7.0
GoString implemented fmt.GoStringer interface, returns a Go-syntax string.
func (Error) WithCode ¶ added in v1.4.0
WithCode returns a copy of err with given code.
BadRequestErr := gear.Err.WithCode(400)
func (Error) WithMsg ¶ added in v1.4.0
WithMsg returns a copy of err with given new messages.
err := gear.Err.WithMsg() // just clone err := gear.ErrBadRequest.WithMsg("invalid email") // 400 Bad Request error with message invalid email"
type HTTPError ¶
type HTTPError interface { // Error returns error's message. Error() string // Status returns error's http status code. Status() int }
HTTPError interface is used to create a server error that include status code and error message.
func ParseError ¶ added in v0.10.0
ParseError parse a error, textproto.Error or HTTPError to HTTPError
type LoggerFilterWriter ¶ added in v1.7.5
type LoggerFilterWriter struct {
// contains filtered or unexported fields
}
LoggerFilterWriter is a writer for Logger to filter bytes. In a https server, avoid some handshake mismatch condition such as loadbalance healthcheck:
2017/06/09 07:18:04 http: TLS handshake error from 10.10.5.1:45001: tls: first record does not look like a TLS handshake 2017/06/14 02:39:29 http: TLS handshake error from 10.0.1.2:54975: read tcp 10.10.5.22:8081->10.0.1.2:54975: read: connection reset by peer
Usage:
func main() { app := gear.New() // Create app app.Use(func(ctx *gear.Context) error { return ctx.HTML(200, "<h1>Hello, Gear!</h1>") }) app.Set(gear.SetLogger, log.New(gear.DefaultFilterWriter(), "", log.LstdFlags)) app.Listen(":3000") }
func DefaultFilterWriter ¶ added in v1.7.5
func DefaultFilterWriter() *LoggerFilterWriter
DefaultFilterWriter returns the default LoggerFilterWriter instance.
func (*LoggerFilterWriter) Add ¶ added in v1.7.5
func (s *LoggerFilterWriter) Add(err string)
Add add a phrase string to filter
func (*LoggerFilterWriter) SetOutput ¶ added in v1.7.5
func (s *LoggerFilterWriter) SetOutput(out io.Writer)
SetOutput sets the output destination for the loggerFilterWriter.
type Middleware ¶
Middleware defines a function to process as middleware.
func Compose ¶ added in v0.26.4
func Compose(mds ...Middleware) Middleware
Compose composes a array of middlewares to one middleware
func WrapHandler ¶ added in v0.3.0
func WrapHandler(handler http.Handler) Middleware
WrapHandler wrap a http.Handler to Gear Middleware
func WrapHandlerFunc ¶ added in v0.3.0
func WrapHandlerFunc(fn http.HandlerFunc) Middleware
WrapHandlerFunc wrap a http.HandlerFunc to Gear Middleware
type Response ¶
type Response struct {
// contains filtered or unexported fields
}
Response wraps an http.ResponseWriter and implements its interface to be used by an HTTP handler to construct an HTTP response.
func (*Response) Body ¶
Body returns the response content. If you use Response.Write directly, the content will not be captured.
func (*Response) CloseNotify ¶ added in v0.20.0
CloseNotify implements the http.CloseNotifier interface to allow detecting when the underlying connection has gone away. This mechanism can be used to cancel long operations on the server if the client has disconnected before the response is ready. See http.CloseNotifier(https://golang.org/pkg/net/http/#CloseNotifier)
func (*Response) Flush ¶ added in v0.20.0
func (r *Response) Flush()
Flush implements the http.Flusher interface to allow an HTTP handler to flush buffered data to the client. See http.Flusher(https://golang.org/pkg/net/http/#Flusher)
func (*Response) Get ¶
Get gets the first value associated with the given key. If there are no values associated with the key, Get returns "". To access multiple values of a key, access the map directly with CanonicalHeaderKey.
func (*Response) HeaderWrote ¶ added in v0.14.0
HeaderWrote indecates that whether the reply header has been (logically) written.
func (*Response) Hijack ¶ added in v0.20.0
Hijack implements the http.Hijacker interface to allow an HTTP handler to take over the connection. See http.Hijacker(https://golang.org/pkg/net/http/#Hijacker)
func (*Response) Push ¶ added in v1.0.0
func (r *Response) Push(target string, opts *http.PushOptions) error
Push implements http.Pusher. Example: https://github.com/teambition/gear/blob/master/example/http2/app.go
func (*Response) ResetHeader ¶ added in v0.16.4
ResetHeader reset headers. If keepSubset is true, header matching `(?i)^(accept|allow|retry-after|warning|access-control-allow-)` will be keep
func (*Response) Set ¶
Set sets the header entries associated with key to the single element value. It replaces any existing values associated with key.
func (*Response) Vary ¶ added in v0.21.0
Vary manipulate the HTTP Vary header. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary
func (*Response) WriteHeader ¶
WriteHeader sends an HTTP response header with status code. If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router is a tire base HTTP request handler for Gear which can be used to dispatch requests to different handler functions. A trivial example is:
package main import ( "fmt" "github.com/teambition/gear" ) func SomeRouterMiddleware(ctx *gear.Context) error { // do some thing. fmt.Println("Router middleware...") return nil } func ViewHello(ctx *gear.Context) error { return ctx.HTML(200, "<h1>Hello, Gear!</h1>") } func main() { app := gear.New() // Add app middleware router := gear.NewRouter() router.Use(SomeRouterMiddleware) // Add router middleware, optionally router.Get("/", ViewHello) app.UseHandler(router) app.Error(app.Listen(":3000")) }
The router matches incoming requests by the request method and the path. If a handle is registered for this path and method, the router delegates the request to that function.
The registered path, against which the router matches incoming requests, can contain six types of parameters:
| Syntax | Description | |--------|------| | `:name` | named parameter | | `:name(regexp)` | named with regexp parameter | | `:name+suffix` | named parameter with suffix matching | | `:name(regexp)+suffix` | named with regexp parameter and suffix matching | | `:name*` | named with catch-all parameter | | `::name` | not named parameter, it is literal `:name` |
Named parameters are dynamic path segments. They match anything until the next '/' or the path end:
Defined: `/api/:type/:ID`
/api/user/123 matched: type="user", ID="123" /api/user no match /api/user/123/comments no match
Named with regexp parameters match anything using regexp until the next '/' or the path end:
Defined: `/api/:type/:ID(^\d+$)`
/api/user/123 matched: type="user", ID="123" /api/user no match /api/user/abc no match /api/user/123/comments no match
Named parameters with suffix, such as [Google API Design](https://cloud.google.com/apis/design/custom_methods):
Defined: `/api/:resource/:ID+:undelete`
/api/file/123 no match /api/file/123:undelete matched: resource="file", ID="123" /api/file/123:undelete/comments no match
Named with regexp parameters and suffix:
Defined: `/api/:resource/:ID(^\d+$)+:cancel`
/api/task/123 no match /api/task/123:cancel matched: resource="task", ID="123" /api/task/abc:cancel no match
Named with catch-all parameters match anything until the path end, including the directory index (the '/' before the catch-all). Since they match anything until the end, catch-all parameters must always be the final path element.
Defined: `/files/:filepath*`
/files no match /files/LICENSE matched: filepath="LICENSE" /files/templates/article.html matched: filepath="templates/article.html"
The value of parameters is saved on the `Matched.Params`. Retrieve the value of a parameter by name:
type := matched.Params("type") id := matched.Params("ID")
More info: https://github.com/teambition/trie-mux
func NewRouter ¶
func NewRouter(routerOptions ...RouterOptions) *Router
NewRouter returns a new Router instance with root path and ignoreCase option. Gear support multi-routers. For example:
// Create app app := gear.New() // Create views router viewRouter := gear.NewRouter() viewRouter.Get("/", Ctl.IndexView) // add more ... apiRouter := gear.NewRouter(RouterOptions{ Root: "/api", IgnoreCase: true, FixedPathRedirect: true, TrailingSlashRedirect: true, }) // support one more middleware apiRouter.Get("/user/:id", API.Auth, API.User) // add more .. app.UseHandler(apiRouter) // Must add apiRouter first. app.UseHandler(viewRouter) // Start app at 3000 app.Listen(":3000")
func (*Router) Delete ¶
func (r *Router) Delete(pattern string, handlers ...Middleware)
Delete registers a new DELETE route for a path with matching handler in the router.
func (*Router) Get ¶
func (r *Router) Get(pattern string, handlers ...Middleware)
Get registers a new GET route for a path with matching handler in the router.
func (*Router) Handle ¶
func (r *Router) Handle(method, pattern string, handlers ...Middleware)
Handle registers a new Middleware handler with method and path in the router. 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 (*Router) Head ¶
func (r *Router) Head(pattern string, handlers ...Middleware)
Head registers a new HEAD route for a path with matching handler in the router.
func (*Router) Options ¶
func (r *Router) Options(pattern string, handlers ...Middleware)
Options registers a new OPTIONS route for a path with matching handler in the router.
func (*Router) Otherwise ¶
func (r *Router) Otherwise(handlers ...Middleware)
Otherwise registers a new Middleware handler in the router that will run if there is no other handler matching.
func (*Router) Patch ¶
func (r *Router) Patch(pattern string, handlers ...Middleware)
Patch registers a new PATCH route for a path with matching handler in the router.
func (*Router) Post ¶
func (r *Router) Post(pattern string, handlers ...Middleware)
Post registers a new POST route for a path with matching handler in the router.
func (*Router) Put ¶
func (r *Router) Put(pattern string, handlers ...Middleware)
Put registers a new PUT route for a path with matching handler in the router.
func (*Router) Use ¶
func (r *Router) Use(handle Middleware)
Use registers a new Middleware in the router, that will be called when router mathed.
type RouterOptions ¶ added in v0.15.0
type RouterOptions struct { // Router's namespace. Gear supports multiple routers with different namespace. // Root string should start with "/", default to "/" Root string // Ignore case when matching URL path. IgnoreCase bool // Enables automatic redirection if the current path can't be matched but // a handler for the fixed path exists. // For example if "/api//foo" is requested but a route only exists for "/api/foo", the // client is redirected to "/api/foo"" with http status code 301 for GET requests // and 307 for all other request methods. FixedPathRedirect bool // 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. TrailingSlashRedirect bool }
RouterOptions is options for Router
type ServerListener ¶ added in v0.6.0
type ServerListener struct {
// contains filtered or unexported fields
}
ServerListener is returned by a non-blocking app instance.
func (*ServerListener) Addr ¶ added in v0.6.0
func (s *ServerListener) Addr() net.Addr
Addr returns the non-blocking app instance addr.
func (*ServerListener) Close ¶ added in v0.6.0
func (s *ServerListener) Close() error
Close closes the non-blocking app instance.
func (*ServerListener) Wait ¶ added in v0.6.0
func (s *ServerListener) Wait() error
Wait make the non-blocking app instance blocking.