ginx

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Apr 20, 2024 License: MIT Imports: 23 Imported by: 0

README

ginx

Static Badge GitHub License go reports

ginx is a simple gin enhancer, features as follows:

  • lightweight and more convenient
  • graceful shutdown
  • support walk router and store metadata
  • hooks at BeforeStarting, AfterSarted, OnShutdown
  • integrated with many useful middleware, like ratelimit,recovery, accesslog, rquestId, cors and so on.

install

go get github.com/ginx-contribs/ginx@latest

usage

see more examples in ginx examples.

quick start
package main

import (
	"github.com/ginx-contribs/ginx"
	"log"
)

func main() {
	server := ginx.New()
	err := server.Spin()
	if err != nil {
		log.Fatal(err)
	}
}
meta group

use the meta group and walk with func.

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/ginx-contribs/ginx"
	"log"
	"log/slog"
)

func main() {
	server := ginx.Default()
	root := server.RouterGroup()
	root.MGET("login", ginx.M{{"role", "guest"}, {"limit", 5}})
	user := root.MGroup("user", nil)
	user.MGET("info", ginx.M{{"role", "user"}}, func(ctx *gin.Context) {
		// get metadata from context
		metaData := ginx.MetaFromCtx(ctx)
		slog.Info(metaData.ShouldGet("role").String())
	})

	// walk root router
	root.Walk(func(info ginx.RouteInfo) {
		slog.Info(fmt.Sprintf("%s %s", info.FullPath, info.Meta))
	})

	err := server.Spin()
	if err != nil {
		log.Fatal(err)
	}
}

output

2024/04/04 12:49:16 INFO / {}
2024/04/04 12:49:16 INFO /login {role:guest,limit:5}
2024/04/04 12:49:16 INFO /user {}
2024/04/04 12:49:16 INFO /user/info {role:user}
2024/04/04 12:49:16 INFO [GinX] server is listening on :8080
2024/04/04 12:49:27 INFO user
2024/04/04 12:49:27 INFO [GinX] status=200 method=GET cost=201.60µs ip=127.0.0.1 url=/user/info path=/user/info route=/user/info request-size=720B response-size=0B
2024/04/04 12:51:16 INFO [GinX] received stop signal, it will shutdown in 5s at latest
2024/04/04 12:51:16 INFO [GinX] server shutdown
use middleware

see more middlewares at ginx middlewares.

package main

import (
	"github.com/ginx-contribs/ginx"
	"github.com/ginx-contribs/ginx/middleware"
	"log"
	"log/slog"
	"time"
)

func main() {
	server := ginx.New(
		ginx.WithNoRoute(middleware.NoRoute()),
		ginx.WithNoMethod(middleware.NoMethod()),
		ginx.WithMiddlewares(
			middleware.Logger(slog.Default(), "ginx"),
			middleware.RateLimit(nil, nil),
			middleware.CacheMemory("cache", time.Second),
		),
	)

	err := server.Spin()
	if err != nil {
		log.Fatal(err)
	}
}
response

ginx provides a unified response body and supports chain calling

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/ginx-contribs/ginx"
	"github.com/ginx-contribs/ginx/pkg/resp"
	"github.com/ginx-contribs/ginx/pkg/resp/statuserr"
	"log"
)

func main() {
	server := ginx.Default()
	root := server.RouterGroup()
	// {"code":200,"data":"hello world!","msg":"ok"}
	root.GET("/hello", func(ctx *gin.Context) {
		resp.Ok(ctx).Data("hello world!").Msg("ok").JSON()
	})

	// {"code":1018,"error":"invalid access"}
	root.GET("/error", func(ctx *gin.Context) {
		resp.Fail(ctx).Error(statuserr.New().SetErrorf("invalid access").SetCode(1018)).JSON()
	})
	err := server.Spin()
	if err != nil {
		log.Fatal(err)
	}
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var GinSilence = true

GinSilence decide whether to keep gin.DefaultWriter and gin.DefaultErrorWriter silence

Functions

func ShouldValidate added in v1.2.2

func ShouldValidate(ctx *gin.Context, val any) error

func ShouldValidateHeader added in v1.2.2

func ShouldValidateHeader(ctx *gin.Context, val any) error

func ShouldValidateJSON added in v1.2.2

func ShouldValidateJSON(ctx *gin.Context, val any) error

func ShouldValidateQuery added in v1.2.2

func ShouldValidateQuery(ctx *gin.Context, val any) error

func ShouldValidateTOML added in v1.2.2

func ShouldValidateTOML(ctx *gin.Context, val any) error

func ShouldValidateURI added in v1.2.2

func ShouldValidateURI(ctx *gin.Context, val any) error

func ShouldValidateWith added in v1.2.2

func ShouldValidateWith(ctx *gin.Context, val any, binding binding.Binding) error

func ShouldValidateXML added in v1.2.2

func ShouldValidateXML(ctx *gin.Context, val any) error

func ShouldValidateYAML added in v1.2.2

func ShouldValidateYAML(ctx *gin.Context, val any) error

Types

type FrozenMap added in v1.3.0

type FrozenMap[K comparable, V any] struct {
	// contains filtered or unexported fields
}

FrozenMap is a thread-safe map, write operations will cause panic after map is frozen.

func (*FrozenMap[K, V]) Del added in v1.3.0

func (r *FrozenMap[K, V]) Del(k K)

func (*FrozenMap[K, V]) Frozen added in v1.3.0

func (r *FrozenMap[K, V]) Frozen()

Frozen make map be immutable

func (*FrozenMap[K, V]) Get added in v1.3.0

func (r *FrozenMap[K, V]) Get(k K) (V, bool)

func (*FrozenMap[K, V]) Range added in v1.3.0

func (r *FrozenMap[K, V]) Range(fn func(K, V))

func (*FrozenMap[K, V]) Set added in v1.3.0

func (r *FrozenMap[K, V]) Set(k K, v V)

type HookFn

type HookFn = func(ctx context.Context) error

HookFn will be executed at specific point

type M

type M []V

M is a group of V

type MetaData

type MetaData struct {
	// contains filtered or unexported fields
}

MetaData is a read map store in memory

func MetaFromCtx

func MetaFromCtx(ctx *gin.Context) MetaData

MetaFromCtx get metadata of route itself from context

func (MetaData) Contains added in v1.2.4

func (m MetaData) Contains(v V) bool

func (MetaData) Get

func (m MetaData) Get(key string) (V, bool)

func (MetaData) Has

func (m MetaData) Has(key string) bool

func (MetaData) MustGet

func (m MetaData) MustGet(key string) V

func (MetaData) ShouldGet

func (m MetaData) ShouldGet(key string) V

func (MetaData) String

func (m MetaData) String() string

type Option

type Option func(options *Server)

func WithAddress

func WithAddress(address string) Option

func WithAfterStarted

func WithAfterStarted(hooks ...HookFn) Option

func WithBeforeStarting

func WithBeforeStarting(hooks ...HookFn) Option

func WithCtx

func WithCtx(ctx context.Context) Option

WithCtx apply the server root context

func WithEngine

func WithEngine(engine *gin.Engine) Option

WithEngine apply a custom engine

func WithHttpServer

func WithHttpServer(httpserver *http.Server) Option

WithHttpServer apply a custom httpserver

func WithIdleTimeout

func WithIdleTimeout(timeout time.Duration) Option

func WithMaxHeaderBytes

func WithMaxHeaderBytes(bytes int) Option

func WithMaxShutdownWait

func WithMaxShutdownWait(timeout time.Duration) Option

func WithMiddlewares

func WithMiddlewares(handlers ...gin.HandlerFunc) Option

func WithMode

func WithMode(mode string) Option

func WithMultipartMem

func WithMultipartMem(mem int64) Option

func WithNoMethod

func WithNoMethod(handlers ...gin.HandlerFunc) Option

func WithNoRoute

func WithNoRoute(handlers ...gin.HandlerFunc) Option

func WithOnShutdown

func WithOnShutdown(hooks ...HookFn) Option

func WithOptions

func WithOptions(options Options) Option

WithOptions apply a whole options

func WithReadHeaderTimeout

func WithReadHeaderTimeout(timeout time.Duration) Option

func WithReadTimeout

func WithReadTimeout(timeout time.Duration) Option

func WithStopSignals

func WithStopSignals(signals ...os.Signal) Option

func WithTLS

func WithTLS(key string, cert string) Option

func WithWriteTimeout

func WithWriteTimeout(timeout time.Duration) Option

type Options

type Options struct {
	Mode string `mapstructure:"mode"`
	// specifies the TCP address for the server to listen on,
	// in the form "host:port". If empty, ":http" (port 80) is used
	Address string `mapstructure:"address"`

	// ReadTimeout is the maximum duration for reading the entire
	// request, including the body. A zero or negative value means
	// there will be no timeout.
	ReadTimeout time.Duration `mapstructure:"readTimeout"`

	// ReadHeaderTimeout is the amount of time allowed to read
	// request headers.
	ReadHeaderTimeout time.Duration `mapstructure:"readHeaderTimeout"`

	// WriteTimeout is the maximum duration before timing out
	// writes of the response.
	WriteTimeout time.Duration `mapstructure:"writeTimeout"`

	// IdleTimeout is the maximum amount of time to wait for the
	// next request when keep-alives are enabled.
	IdleTimeout time.Duration `mapstructure:"idleTimeout"`

	// MaxMultipartMemory value of 'maxMemory' param that is given to http.Request's ParseMultipartForm
	// method call.
	MaxMultipartMemory int64 `mapstructure:"xaxMultipartMemory"`

	// MaxHeaderBytes controls the maximum number of bytes the
	// server will read parsing the request header's keys and
	// values, including the request line.
	MaxHeaderBytes int `mapstructure:"maxHeaderBytes"`

	// simple TLS config
	TLS *TLSOptions `mapstructure:"tls"`

	// max wait time after server shutdown
	MaxShutdownTimeout time.Duration `mapstructure:"maxShutdownTimeout"`
}

type RouteInfo

type RouteInfo struct {
	IsGroup bool
	Group   *RouteInfo

	Method   string
	FullPath string
	Handler  gin.HandlerFunc
	Meta     MetaData
}

RouteInfo includes basic router information, it will be passed to walkFn in *RouterGroup.Walk.

type RouterGroup

type RouterGroup struct {
	// contains filtered or unexported fields
}

func (*RouterGroup) Any

func (group *RouterGroup) Any(path string, handlers ...gin.HandlerFunc) []*RouterHandler

func (*RouterGroup) DELETE

func (group *RouterGroup) DELETE(path string, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) GET

func (group *RouterGroup) GET(path string, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) Group

func (group *RouterGroup) Group(path string, handlers ...gin.HandlerFunc) *RouterGroup

func (*RouterGroup) HEAD

func (group *RouterGroup) HEAD(path string, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) Handle

func (group *RouterGroup) Handle(method string, path string, meta M, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) MAny

func (group *RouterGroup) MAny(path string, meta M, handlers ...gin.HandlerFunc) []*RouterHandler

func (*RouterGroup) MDELETE

func (group *RouterGroup) MDELETE(path string, meta M, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) MGET

func (group *RouterGroup) MGET(path string, meta M, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) MGroup

func (group *RouterGroup) MGroup(path string, meta M, handlers ...gin.HandlerFunc) *RouterGroup

MGroup creates a new router group with the given metadata that will ba applied into its sub handlers.

func (*RouterGroup) MHEAD

func (group *RouterGroup) MHEAD(path string, meta M, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) MOPTIONS

func (group *RouterGroup) MOPTIONS(path string, meta M, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) MPOST

func (group *RouterGroup) MPOST(path string, meta M, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) MPUT

func (group *RouterGroup) MPUT(path string, meta M, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) Match

func (group *RouterGroup) Match(methods []string, path string, meta M, handlers ...gin.HandlerFunc) []*RouterHandler

func (*RouterGroup) OPTIONS

func (group *RouterGroup) OPTIONS(path string, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) POST

func (group *RouterGroup) POST(path string, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) PUT

func (group *RouterGroup) PUT(path string, handlers ...gin.HandlerFunc) *RouterHandler

func (*RouterGroup) Use

func (group *RouterGroup) Use(handlers ...gin.HandlerFunc)

Use same as *gin.RouterGroup.Use()

func (*RouterGroup) Walk

func (group *RouterGroup) Walk(walkFn func(info RouteInfo))

Walk group and handlers info, include subgroup

type RouterHandler

type RouterHandler struct {
	Method   string
	FullPath string
	// contains filtered or unexported fields
}

RouterHandler represents a single route handler

type Server

type Server struct {

	// hooks func
	BeforeStarting []HookFn
	AfterStarted   []HookFn
	OnShutdown     []HookFn
	// contains filtered or unexported fields
}

Server is a simple wrapper for http.Server and *gin.Engine, which is more convenient to use. It provides hooks can be executed at certain time, ability to graceful shutdown.

func Default

func Default() *Server

Default returns *Server with default middlewares

func New

func New(options ...Option) *Server

New returns a new server instance

func (*Server) Engine

func (s *Server) Engine() *gin.Engine

func (*Server) HttpServer

func (s *Server) HttpServer() *http.Server

func (*Server) RouterGroup

func (s *Server) RouterGroup() *RouterGroup

RouterGroup returns metadata route group

func (*Server) Run

func (s *Server) Run() error

Run just run the http server without hooks, you should use *Server.Spin` im most time.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

func (*Server) Spin

func (s *Server) Spin() error

Spin runs the server in another go routine, and listening for os signals to graceful shutdown,

type TLSOptions

type TLSOptions struct {
	// TLS Key file
	Key string `mapstructure:"key"`
	// TLS Certificate file
	Cert string `mapstructure:"cert"`
}

type V

type V struct {
	Key string
	Val any
}

V is basic item in metadata

func (V) Bool

func (v V) Bool() bool

func (V) Duration

func (v V) Duration() time.Duration

func (V) Float32

func (v V) Float32() float32

func (V) Float64

func (v V) Float64() float64

func (V) Int

func (v V) Int() int

func (V) Int16

func (v V) Int16() int16

func (V) Int32

func (v V) Int32() int32

func (V) Int64

func (v V) Int64() int64

func (V) Int8

func (v V) Int8() int8

func (V) String

func (v V) String() string

func (V) Time

func (v V) Time() time.Time

func (V) Uint

func (v V) Uint() uint

func (V) Uint16

func (v V) Uint16() uint16

func (V) Uint32

func (v V) Uint32() uint32

func (V) Uint64

func (v V) Uint64() uint64

func (V) Uint8

func (v V) Uint8() uint8

func (V) Value

func (v V) Value() any

type ValidateHandler added in v1.2.2

type ValidateHandler func(ctx *gin.Context, val any, err error)

ValidateHandler will be called if validate failed.

var DefaultValidateHandler ValidateHandler = func(ctx *gin.Context, val any, err error) {
	response := resp.Fail(ctx).Error(err)
	if _, ok := err.(validator.ValidationErrors); ok {
		response = response.Msg("invalid parameters")
	} else {
		response = response.Status(status.InternalServerError).Msg(status.InternalServerError.String())
	}
	response.JSON()
}

Jump to

Keyboard shortcuts

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