Categorygithub.com/teambition/gear
modulepackage
1.27.3
Repository: https://github.com/teambition/gear.git
Documentation: pkg.go.dev

# README

Gear

CI Codecov CodeQL Go Reference License

A lightweight, composable and high performance web service framework for Go.

Features

  • Effective and flexible middlewares flow control, create anything by middleware
  • Powerful and smart HTTP error handling
  • Trie base gear.Router, as faster as HttpRouter, support regexp parameters and group routes
  • Integrated timeout context.Context
  • Integrated response content compress
  • Integrated structured logging middleware
  • Integrated request body parser
  • Integrated signed cookies
  • Integrated JSON, JSONP, XML and HTML renderer
  • Integrated CORS, Secure, Favicon and Static middlewares
  • More useful methods on gear.Context to manipulate HTTP Request/Response
  • Run HTTP and gRPC on the same port
  • Completely HTTP/2.0 supported

Documentation

Go-Documentation

Import

// package gear
import "github.com/teambition/gear"

Design

  1. Server 底层基于原生 net/http 而不是 fasthttp
  2. 通过 gear.Middleware 中间件模式扩展功能模块
  3. 中间件的单向顺序流程控制和级联流程控制
  4. 功能强大,完美集成 context.Context 的 gear.Context
  5. 集中、智能、可自定义的错误和异常处理
  6. After Hook 和 End Hook 的后置处理
  7. Any interface 无限的 gear.Context 状态扩展能力
  8. 请求数据的解析和验证

FAQ

  1. 如何从源码自动生成 Swagger v2 的文档?
  2. Go 语言完整的应用项目结构最佳实践是怎样的?

Demo

Hello

https://github.com/teambition/gear/tree/master/example/hello

  app := gear.New()

  // Add logging middleware
  app.UseHandler(logging.Default(true))

  // Add router middleware
  router := gear.NewRouter()

  // try: http://127.0.0.1:3000/hello
  router.Get("/hello", func(ctx *gear.Context) error {
    return ctx.HTML(200, "<h1>Hello, Gear!</h1>")
  })

  // try: http://127.0.0.1:3000/test?query=hello
  router.Otherwise(func(ctx *gear.Context) error {
    return ctx.JSON(200, map[string]any{
      "Host":    ctx.Host,
      "Method":  ctx.Method,
      "Path":    ctx.Path,
      "URI":     ctx.Req.RequestURI,
      "Headers": ctx.Req.Header,
    })
  })
  app.UseHandler(router)
  app.Error(app.Listen(":3000"))

HTTP2 with Push

https://github.com/teambition/gear/tree/master/example/http2

package main

import (
  "net/http"

  "github.com/teambition/gear"
  "github.com/teambition/gear/logging"
  "github.com/teambition/gear/middleware/favicon"
)

// go run example/http2/app.go
// Visit: https://127.0.0.1:3000/
func main() {
  const htmlBody = `
<!DOCTYPE html>
<html>
  <head>
    <link href="/hello.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <h1>Hello, Gear!</h1>
  </body>
</html>`

  const pushBody = `
h1 {
  color: red;
}
`

  app := gear.New()

  app.UseHandler(logging.Default(true))
  app.Use(favicon.New("./testdata/favicon.ico"))

  router := gear.NewRouter()
  router.Get("/", func(ctx *gear.Context) error {
    ctx.Res.Push("/hello.css", &http.PushOptions{Method: "GET"})
    return ctx.HTML(200, htmlBody)
  })
  router.Get("/hello.css", func(ctx *gear.Context) error {
    ctx.Type("text/css")
    return ctx.End(200, []byte(pushBody))
  })
  app.UseHandler(router)
  app.Error(app.ListenTLS(":3000", "./testdata/out/test.crt", "./testdata/out/test.key"))
}

A CMD tool: static server

https://github.com/teambition/gear/tree/master/example/staticgo

Install it with go:

go install github.com/teambition/gear/example/staticgo@latest

It is a useful CMD tool that serve your local files as web server (support TLS). You can build osx, linux, windows version with make build.

package main

import (
  "flag"

  "github.com/teambition/gear"
  "github.com/teambition/gear/logging"
  "github.com/teambition/gear/middleware/cors"
  "github.com/teambition/gear/middleware/static"
)

var (
  address  = flag.String("addr", "127.0.0.1:3000", `address to listen on.`)
  path     = flag.String("path", "./", `static files path to serve.`)
  certFile = flag.String("certFile", "", `certFile path, used to create TLS static server.`)
  keyFile  = flag.String("keyFile", "", `keyFile path, used to create TLS static server.`)
)

func main() {
  flag.Parse()
  app := gear.New()

  app.UseHandler(logging.Default(true))
  app.Use(cors.New())
  app.Use(static.New(static.Options{Root: *path}))

  logging.Println("staticgo v1.2.0, created by https://github.com/teambition/gear")
  logging.Printf("listen: %s, serve: %s\n", *address, *path)

  if *certFile != "" && *keyFile != "" {
    app.Error(app.ListenTLS(*address, *certFile, *keyFile))
  } else {
    app.Error(app.Listen(*address))
  }
}

A CMD tool: reverse proxy server

https://github.com/teambition/gear/tree/master/example/gearproxy

Install it with go:

go install github.com/teambition/gear/example/gearproxy@latest
gearproxy -help

HTTP2 & gRPC

https://github.com/teambition/gear/tree/master/example/grpc_server

https://github.com/teambition/gear/tree/master/example/grpc_client

About Router

gear.Router is a trie base HTTP request handler. Features:

  1. Support named parameter
  2. Support regexp
  3. Support suffix matching
  4. Support multi-router
  5. Support router layer middlewares
  6. Support fixed path automatic redirection
  7. Support trailing slash automatic redirection
  8. Automatic handle 405 Method Not Allowed
  9. Automatic handle OPTIONS method
  10. Best Performance

The registered path, against which the router matches incoming requests, can contain six types of parameters:

SyntaxDescription
:namenamed parameter
:name(regexp)named with regexp parameter
:name+suffixnamed parameter with suffix matching
:name(regexp)+suffixnamed with regexp parameter and suffix matching
:name*named with catch-all parameter
::namenot 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:

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 Middlewares

License

Gear is licensed under the MIT license. Copyright © 2016-2023 Teambition.

# Packages

No description provided by the author
No description provided by the author
No description provided by the author

# Functions

Compose composes a slice of middlewares to one middleware.
ContentDisposition implements a simple version of https://tools.ietf.org/html/rfc2183 Use mime.ParseMediaType to parse Content-Disposition header.
ContextWithSignal creates a context canceled when SIGINT or SIGTERM are notified Usage: func main() { app := gear.New() // Create app do some thing..
CtxDoIf calls the function fn with the value *T stored in the context.Context.
CtxValue returns the value *T stored in the context.Context, or nil if not stored.
CtxWith returns a new context.Context with the value *T stored in it.
Decompress wrap the reader for decompressing, It support gzip and zlib, and compatible for deflate.
DefaultFilterWriter returns the default LoggerFilterWriter instance.
ErrByStatus returns a gear.Error by http status.
ErrorWithStack create a error with stacktrace.
GetRouterNodeFromCtx returns matched Node from router router.Get("/api/:type/:ID", func(ctx *Context) error { assert.Equal("/api/:type/:ID", GetRouterNodeFromCtx(ctx).GetPattern()) return ctx.HTML(200, ctx.Param("type")+ctx.Param("ID")) }).
GetRouterPatternFromCtx returns matched Node from router routerV2.Get("/api/:type/:ID", func(ctx *Context) error { assert.Equal("/v2/api/:type/:ID", GetRouterPatternFromCtx(ctx)) return ctx.HTML(200, "ok") }).
IsNil checks if a specified object is nil or not, without failing.
IsStatusCode returns true if status is HTTP status code.
New creates an instance of App.
NewContext creates an instance of Context.
NewRouter returns a new Router instance with root path and ignoreCase option.
ParseError parse a error, textproto.Error or HTTPError to HTTPError.
RenderErrorResponse is a SetRenderError function with ErrorResponse struct.
ToErrorResponse convert a error to ErrorResponse instance.
ValuesToStruct converts url.Values into struct object.
WrapHandler wrap a http.Handler to Gear Middleware.
WrapHandlerFunc wrap a http.HandlerFunc to Gear Middleware.

# Constants

Requests, Responses.
Requests.
Requests.
Requests.
Requests.
Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Requests.
Requests, Responses.
Responses.
Responses.
Responses.
Requests, Responses.
Responses.
Requests, Responses.
Responses.
Responses.
Responses.
Requests, Responses.
Requests.
Responses.
Responses.
Requests.
Requests.
Requests.
Requests.
Requests.
Responses.
Responses.
Responses.
Requests.
Requests.
Responses.
Requests, Responses.
Responses.
Requests.
Responses.
Responses.
Requests.
Requests.
Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Requests.
Responses.
Responses.
Requests.
Responses.
Requests.
Requests, Responses.
Responses.
Requests, Responses.
Responses.
Responses.
Responses.
Responses.
Responses.
Requests.
Requests.
Requests.
Requests.
Requests.
Responses.
Responses.
Responses.
Requests.
Requests.
Requests.
Requests.
Responses.
Responses.
Responses.
MIME types.
MIME types.
MIME types.
MIME types.
Got from https://github.com/labstack/echo.
MIME types.
https://tools.ietf.org/html/draft-rfernando-protocol-buffers-00.
MIME types.
MIME types.
MIME types.
MIME types.
https://github.com/toml-lang/toml.
MIME types.
MIME types.
MIME types.
MIME types.
MIME types.
MIME types.
MIME types.
MIME types.
MIME types.
MIME types.
MIME types.
It will be used by `ctx.ParseBody`, value should implements `gear.BodyParser` interface, default to: app.Set(gear.SetBodyParser, gear.DefaultBodyParser(1<<20)).
Enable compress for response, value should implements `gear.Compressible` interface, no default value.
Set a app env string to app, it can be retrieved by `ctx.Setting(gear.SetEnv)`.
Set a graceful timeout to for gracefully shuts down, value should be `time.Duration`.
Set secret keys for signed cookies, it will be used by `ctx.Cookies`, value should be `[]string` type, no default value.
Set a logger to app, value should be `*log.Logger` instance, default to: app.Set(gear.SetLogger, log.New(os.Stderr, "", 0)) Maybe you need LoggerFilterWriter to filter some server errors in production: app.Set(gear.SetLogger, log.New(gear.DefaultFilterWriter(), "", 0)) We recommand set logger flags to 0.
Set a on-error hook to app that handle middleware error.
Set a ParseError hook to app that convert middleware error to HTTPError, value should be `func(err error) HTTPError`, default to: app.Set(SetParseError, func(err error) HTTPError { return ParseError(err) }).
Set a renderer to app, it will be used by `ctx.Render`, value should implements `gear.Renderer` interface, no default value.
Set a SetRenderError hook to app that convert error to raw response, value should be `func(HTTPError) (code int, contentType string, body []byte)`, default to: app.Set(SetRenderError, func(err HTTPError) (int, string, []byte) { // default to render error as json body, e := json.Marshal(err) if e != nil { body, _ = json.Marshal(map[string]string{"error": err.Error()}) } return err.Status(), MIMEApplicationJSONCharsetUTF8, body }) you can use another recommand one: app.Set(gear.SetRenderError, gear.RenderErrorResponse) .
Set a SetSender to app, it will be used by `ctx.Send`, value should implements `gear.Sender` interface, no default value.
Set a server name that respond to client as "Server" header.
Set a timeout to for the middleware process, value should be `time.Duration`.
Set true and proxy header fields will be trusted Default to false.
It will be used by `ctx.ParseURL`, value should implements `gear.URLParser` interface, default to: app.Set(gear.SetURLParser, gear.DefaultURLParser).
Set a function that Wrap the gear.Context' underlayer context.Context.
Version is Gear's version.

# Variables

Predefined errors.
Predefined errors.
https://golang.org/pkg/net/http/#pkg-constants.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.
Predefined errors.

# Structs

App is the top-level framework struct.
Context represents the context of the current HTTP request.
DefaultCompress is defalut Compress implemented.
DefaultURLParser is default URLParser type.
Error represents a numeric error with optional meta.
ErrorResponse represents error response like JSON-RPC2 or Google cloud API.
LoggerFilterWriter is a writer for Logger to filter bytes.
Response wraps an http.ResponseWriter and implements its interface to be used by an HTTP handler to construct an HTTP response.
Router is a trie base HTTP request handler for Gear which can be used to dispatch requests to different handler functions.
RouterOptions is options for Router.
ServerListener is returned by a non-blocking app instance.
State is the recommended namespace for passing information through middleware and handlers.

# Interfaces

Any interface is used by ctx.Any.
BodyParser interface is used by ctx.ParseBody.
BodyTemplate interface is used by ctx.ParseBody.
Compressible interface is use to enable compress response content.
Handler interface is used by app.UseHandler as a middleware.
HTTPError interface is used to create a server error that include status code and error message.
IsValid is a generic interface for `gear.CtxDoIf`.
Renderer interface is used by ctx.Render.
Sender interface is used by ctx.Send.
URLParser interface is used by ctx.ParseUrl.

# Type aliases

DefaultBodyParser is default BodyParser type.
Middleware defines a function to process as middleware.
ThresholdCompress is an impelementation with transhold.