Overview

Kratos has a series of built-in middleware to deal with common purpose such as logging or metrics. You could also implement Middleware interface to develop your custom middleware to process common business such as the user authentication etc.

Built-in Middleware

Their codes are located in middleware directory.

logging

In middleware/logging, this middleware is for logging the request.

metrics

In middleware/metrics, this middleware is for enabling metric.

recovery

In middleware/recovery,, this middleware is for panic recovery.

status

In middleware/status, this middleware is for transformation of gRPC error.

tracing

In middleware/tracing, this middleware is for enabling trace.

validate

In middleware/validate, this middleware is for parameter validation.

auth

In middleware/auth, this middleware is for authority check using JWT.

ratelimit

In middleware/ratelimit, this middleware is for traffic control in server side.

circuitbreaker

In middleware/circuitbreaker, this middleware is for breaker control in client side.

Usage

Register it with ServerOption in NewGRPCServer or NewHTTPServer.

For example:

  1. // http
  2. // define opts
  3. var opts = []http.ServerOption{
  4. http.Middleware(
  5. recovery.Recovery(),
  6. tracing.Server(),
  7. logging.Server(),
  8. ),
  9. }
  10. // create server
  11. http.NewServer(opts...)
  12. //grpc
  13. var opts = []grpc.ServerOption{
  14. grpc.Middleware(
  15. recovery.Recovery(),
  16. status.Server(),
  17. tracing.Server(),
  18. logging.Server(),
  19. ),
  20. }
  21. // create server
  22. grpc.NewServer(opts...)

Custom Middleware

Customized middleware for specific routes

  • server:selector.Server(ms...)
  • client:selector.Client(ms...)

Matching rule (multi parameter)

  • Path(path...) path match

  • Regex(regex...) regex match

  • Prefix(prefix...) prefix path match

  • Match(fn) function match, The function format is func(ctx context.Context,operation string) bool,

    operation is path,If the return value is true,match successful, ctx for transport.FromServerContext(ctx) or transport.FromClientContext(ctx get Transporter

http server

  1. import "github.com/go-kratos/kratos/v2/middleware/selector"
  2. http.Middleware(
  3. selector.Server(recovery.Recovery(), tracing.Server(),testMiddleware).
  4. Path("/hello.Update/UpdateUser", "/hello.kratos/SayHello").
  5. Regex(`/test.hello/Get[0-9]+`).
  6. Prefix("/kratos.", "/go-kratos.", "/helloworld.Greeter/").
  7. Build(),
  8. )

http client

  1. import "github.com/go-kratos/kratos/v2/middleware/selector"
  2. http.WithMiddleware(
  3. selector.Client(recovery.Recovery(), tracing.Server(),testMiddleware).
  4. Path("/hello.Update/UpdateUser", "/hello.kratos/SayHello").
  5. Regex(`/test.hello/Get[0-9]+`).
  6. Prefix("/kratos.", "/go-kratos.", "/helloworld.Greeter/").
  7. Match(func(ctx context.Context,operation string) bool {
  8. if strings.HasPrefix(operation, "/go-kratos.dev") || strings.HasSuffix(operation, "world") {
  9. return true
  10. }
  11. tr, ok := transport.FromClientContext(ctx)
  12. if !ok {
  13. return false
  14. }
  15. if tr.RequestHeader().Get("go-kratos") == "kratos" {
  16. return true
  17. }
  18. return false
  19. }).Build(),
  20. )

grpc server

  1. import "github.com/go-kratos/kratos/v2/middleware/selector"
  2. grpc.Middleware(
  3. selector.Server(recovery.Recovery(), tracing.Server(),testMiddleware).
  4. Path("/hello.Update/UpdateUser", "/hello.kratos/SayHello").
  5. Regex(`/test.hello/Get[0-9]+`).
  6. Prefix("/kratos.", "/go-kratos.", "/helloworld.Greeter/").
  7. Build(),
  8. )

grpc client

  1. import "github.com/go-kratos/kratos/v2/middleware/selector"
  2. grpc.Middleware(
  3. selector.Client(recovery.Recovery(), tracing.Server(),testMiddleware).
  4. Path("/hello.Update/UpdateUser", "/hello.kratos/SayHello").
  5. Regex(`/test.hello/Get[0-9]+`).
  6. Prefix("/kratos.", "/go-kratos.", "/helloworld.Greeter/").
  7. Build(),
  8. )

Note: the customized middleware matches through operation, not is the HTTP routing!!!

operation is the unified GRC path of HTTP and GRC

operation find

gRPC path’s splicing rule is /package.service/method

For example, in the following proto file,if we want to call the sayhello method, then the operation is /helloworld.Greeter/SayHello

  1. syntax = "proto3";
  2. package helloworld;
  3. import "google/api/annotations.proto";
  4. option go_package = "github.com/go-kratos/examples/helloworld/helloworld";
  5. // The greeting service definition.
  6. service Greeter {
  7. // Sends a greeting
  8. rpc SayHello (HelloRequest) returns (HelloReply) {
  9. option (google.api.http) = {
  10. get: "/helloworld/{name}",
  11. };
  12. }
  13. }
  14. // The request message containing the user's name.
  15. message HelloRequest {
  16. string name = 1;
  17. }
  18. // The response message containing the greetings
  19. message HelloReply {
  20. string message = 1;
  21. }