package
1.12.6
Repository: https://github.com/go-dev-frame/sponge.git
Documentation: pkg.go.dev

# README

middleware

Gin middleware plugin.


Example of use

logging middleware

You can set the maximum length for printing, add a request id field, ignore print path, customize zap log.

    import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

    r := gin.Default()

    // default
    r.Use(middleware.Logging()) // simplified logging using middleware.SimpleLog()

    // --- or ---

    // custom
    r.Use(middleware.Logging(    // simplified logging using middleware.SimpleLog(WithRequestIDFromHeader())
        middleware.WithMaxLen(400),
        WithRequestIDFromHeader(),
        //WithRequestIDFromContext(),
        //middleware.WithLog(log), // custom zap log
        //middleware.WithIgnoreRoutes("/hello"),
    ))

Allow cross-domain requests middleware

    import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

    r := gin.Default()
    r.Use(middleware.Cors())

rate limiter middleware

Adaptive flow limitation based on hardware resources.

    import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

    r := gin.Default()

    // default
    r.Use(middleware.RateLimit())

    // --- or ---

    // custom
    r.Use(middleware.RateLimit(
        WithWindow(time.Second*10),
        WithBucket(100),
        WithCPUThreshold(100),
        WithCPUQuota(0.5),
    ))

Circuit Breaker middleware

    import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

    r := gin.Default()
    r.Use(middleware.CircuitBreaker(
        //middleware.WithValidCode(http.StatusRequestTimeout), // add error code 408 for circuit breaker
        //middleware.WithDegradeHandler(handler), // add custom degrade handler
    ))

jwt authorization middleware

JWT supports two verification methods:

  • The default verification method includes fixed fields uid and name in the claim, and supports additional custom verification functions.
  • The custom verification method allows users to define the claim themselves and also supports additional custom verification functions.
package main

import "github.com/go-dev-frame/sponge/pkg/jwt"
import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

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

    r.POST("/user/login", Login)

    // Choose to use one of the following 4 authorization

    // case 1: default authorization
    r.GET("/user/:id", middleware.Auth(), h.GetByID)
    r.GET("/user/:id", middleware.Auth(middleware.WithDefaultVerify()), h.GetByID) // equivalent to middleware.Auth()

	// case 2: default authorization with extra verification
	r.GET("/user/:id", middleware.Auth(middleware.WithDefaultVerify(extraDefaultVerifyFn)), h.GetByID)

	// case 3: custom authorization
	r.GET("/user/:id", middleware.Auth(middleware.WithCustomVerify()), h.GetByID)

    // case 4: custom authorization with extra verification
    r.GET("/user/:id", middleware.Auth(middleware.WithCustomVerify(extraCustomVerifyFn)), h.GetByID)

    r.Run(serverAddr)
}

func Login(c *gin.Context) {
	// ......

	// case 1: generate token with default fields
	token, err := jwt.GenerateToken("123", "admin")
	
	// case 2: generate token with custom fields
	fields := jwt.KV{"id": uint64(100), "name": "tom", "age": 10}
	token, err := jwt.GenerateCustomToken(fields)

	// ......
}

func GetByID(c *gin.Context) {}

func extraDefaultVerifyFn(claims *jwt.Claims, tokenTail10 string, c *gin.Context) error {
	// In addition to jwt certification, additional checks can be customized here.

	// err := errors.New("verify failed")
	// if claims.Name != "admin" {
	//     return err
	// }
	// token := getToken(claims.UID) // from cache or database
	// if tokenTail10 != token[len(token)-10:] { return err }

	return nil
}

func extraCustomVerifyFn(claims *jwt.CustomClaims, tokenTail10 string, c *gin.Context) error {
	// In addition to jwt certification, additional checks can be customized here.

	// err := errors.New("verify failed")
	// token, fields := getToken(id) // from cache or database
	// if tokenTail10 != token[len(token)-10:] { return err }

	// id, exist := claims.GetUint64("id")
	// if !exist || id != fields["id"].(uint64) { return err }

	// name, exist := claims.GetString("name")
	// if !exist || name != fields["name"].(string) { return err }

	// age, exist := claims.GetInt("age")
	// if !exist || age != fields["age"].(int) { return err }

	return nil
}

tracing middleware

import "github.com/go-dev-frame/sponge/pkg/tracer"
import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

func InitTrace(serviceName string) {
	exporter, err := tracer.NewJaegerAgentExporter("192.168.3.37", "6831")
	if err != nil {
		panic(err)
	}

	resource := tracer.NewResource(
		tracer.WithServiceName(serviceName),
		tracer.WithEnvironment("dev"),
		tracer.WithServiceVersion("demo"),
	)

	tracer.Init(exporter, resource) // collect all by default
}

func NewRouter(
	r := gin.Default()
	r.Use(middleware.Tracing("your-service-name"))

	// ......
)

// if necessary, you can create a span in the program
func SpanDemo(serviceName string, spanName string, ctx context.Context) {
	_, span := otel.Tracer(serviceName).Start(
		ctx, spanName,
		trace.WithAttributes(attribute.String(spanName, time.Now().String())),
	)
	defer span.End()

	// ......
}

Metrics middleware

    import "github.com/go-dev-frame/sponge/pkg/gin/middleware/metrics"

    r := gin.Default()

    r.Use(metrics.Metrics(r,
        //metrics.WithMetricsPath("/demo/metrics"), // default is /metrics
        metrics.WithIgnoreStatusCodes(http.StatusNotFound), // ignore status codes
        //metrics.WithIgnoreRequestMethods(http.MethodHead),  // ignore request methods
        //metrics.WithIgnoreRequestPaths("/ping", "/health"), // ignore request paths
    ))

Request id

    import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

    // Default request id
    r := gin.Default()
    r.Use(middleware.RequestID())

    // --- or ---

    // Customized request id key
    //r.User(middleware.RequestID(
    //    middleware.WithContextRequestIDKey("your ctx request id key"), // default is request_id
    //    middleware.WithHeaderRequestIDKey("your header request id key"), // default is X-Request-Id
    //))
    // If you change the ContextRequestIDKey, you have to set the same key name if you want to print the request id in the mysql logs as well.
    // example: 
    // db, err := mysql.Init(dsn,
        // mysql.WithLogRequestIDKey("your ctx request id key"),  // print request_id
        // ...
    // )

Timeout

    import "github.com/go-dev-frame/sponge/pkg/gin/middleware"

    r := gin.Default()

    // way1: global set timeout
    r.Use(middleware.Timeout(time.Second*5))

    // --- or ---

    // way2: router set timeout
    r.GET("/userExample/:id", middleware.Timeout(time.Second*3), h.GetByID)

    // Note: If timeout is set both globally and in the router, the minimum timeout prevails

# Packages

Package metrics is gin metrics library, collect five metrics, "uptime", "http_request_count_total", "http_request_duration_seconds", "http_request_size_bytes", "http_response_size_bytes".

# Functions

AdaptCtx adapt context, if ctx is gin.Context, return gin.Context and context of the transformation.
Auth authorization.
AuthCustom custom authentication Deprecated: use Auth(WithCustomVerify()) instead.
CircuitBreaker a circuit breaker middleware.
Cors cross domain.
CtxRequestID get request id from context.Context.
CtxRequestIDField get request id field from context.Context.
GCtxRequestID get request id from gin.Context.
GCtxRequestIDField get request id field from gin.Context.
GetFromCtx get value from context.
GetFromHeader get value from header.
GetFromHeaders get values from header.
HeaderRequestID get request id from the header.
HeaderRequestIDField get request id field from header.
Logging print request and response info.
RateLimit an adaptive rate limiter middleware.
RequestID is an interceptor that injects a 'request id' into the context and request/response header of each request.
SimpleLog print response info.
Timeout request time out.
Tracing returns interceptor that will trace incoming requests.
WithBucket with bucket size.
WithContextRequestIDKey set context request id key, minimum length of 4.
WithCPUQuota with real cpu quota(if it can not collect from process correct);.
WithCPUThreshold with cpu threshold.
WithCustomVerify set custom verify type with extra verify function.
WithDefaultVerify set default verify type.
WithDegradeHandler set degrade handler function.
WithGroup with circuit breaker group.
WithHeaderRequestIDKey set header request id key, minimum length of 4.
WithIgnoreRoutes no logger content routes.
WithLog set log.
WithMaxLen logger content max length.
WithPropagators specifies propagators to use for extracting information from the HTTP requests.
WithRequestIDFromContext name is field in context, default value is request_id.
WithRequestIDFromHeader name is field in header, default value is X-Request-Id.
WithSwitchHTTPCode switch to http code.
WithTracerProvider specifies a tracer provider to use for creating a tracer.
WithValidCode http code to mark failed.
WithWindow with window size.
WrapCtx wrap context, put the Keys and Header of gin.Context into context.

# Constants

HeaderAuthorizationKey http header authorization key.

# Variables

ContextRequestIDKey request id for context.
ErrLimitExceed is returned when the rate limiter is triggered and the request is rejected due to limit exceeded.
ErrNotAllowed error not allowed.
HeaderXRequestIDKey header request id key.
RequestHeaderKey request header key.
RequestIDKey request_id.

# Type aliases

AuthOption set the auth options.
CircuitBreakerOption set the circuit breaker circuitBreakerOptions.
CtxKeyString for context.WithValue key type.
ExtraCustomVerifyFn extra custom verify function, tokenTail10 is the last 10 characters of the token.
ExtraDefaultVerifyFn extra default verify function, tokenTail10 is the last 10 characters of the token.
JwtOption set the auth options.
Option set the gin logger options.
RateLimitOption set the rate limits rateLimitOptions.
RequestIDOption set the request id options.
TraceOption specifies instrumentation configuration options.
VerifyCustomFn extra custom verify function, tokenTail10 is the last 10 characters of the token.
VerifyFn verify function, tokenTail10 is the last 10 characters of the token.