Kratos

repository·main·Indexed 12 days ago

https://github.com/go-kratos/kratos

A lightweight Go framework for building cloud-native microservices. Kratos emphasizes API-first development using Protobuf and provides composable APIs for transport, middleware, registry, and configuration, including support for v3 configuration sources like Apollo, etcd, Consul, Nacos, Polaris, and Kubernetes.

Tokens
52.3K
Snippets
201
Records
248
Agent score
97%

What's inside Kratos

  1. What is Kratos?

    main

    Kratos is a lightweight Go microservices framework. It provides core capabilities for:

    • Transport: Unified abstraction for HTTP and gRPC.
    • Middleware: Composable layers for Recovery, Logging, Validation, Tracing, Metrics, and Auth.
    • Registry & Config: Plugin-based service discovery and configuration management.
    • Encoding: Extensible encoding capabilities.
    • Observability: Logging based on the standard library log/slog, with OpenTelemetry extensions provided via contrib packages.
    • Code Generation: Protobuf-centric API definitions and automated code generation.
  2. Use Validator Middleware with protovalidate

    main

    The Kratos Validator middleware allows for automatic validation of request parameters based on schemas defined in .proto files.

    This module uses protovalidate instead of the legacy PGV (protoc-gen-validate) to provide validation functions. While protovalidate typically does not require build-time code generation, this middleware enables a legacy mode to maintain compatibility with existing Kratos projects.

    Migration Note: If you have manually implemented the Validator interface in your project, you must migrate your implementation to align with the new middleware requirements.

  3. OpenTelemetry Contrib Packages Overview

    main

    The contrib/otel module contains OpenTelemetry integrations kept separate from the Kratos core. It is organized into three main subpackages:

    • github.com/go-kratos/kratos/contrib/otel/v3/log: Provides a slog handler bridge via otel.NewHandler.
    • github.com/go-kratos/kratos/contrib/otel/v3/tracing: Provides tracing middleware and trace slog attributes.
    • github.com/go-kratos/kratos/contrib/otel/v3/metrics: Provides metrics middleware and OpenTelemetry metric helpers.
  4. Explicitly select a JSON Codec in v3

    main

    In v3, the JSON codec is split to avoid implicit behavior. You must explicitly import the codec you intend to use:

    • github.com/go-kratos/kratos/v3/encoding/json: Registers the standard library JSON codec (named json).
    • github.com/go-kratos/kratos/v3/encoding/protojson: Registers the protobuf JSON codec (named protojson).
    • github.com/go-kratos/kratos/contrib/encoding/json/v3: Provides v2-compatible behavior for services that rely on automatic protobuf message handling via the json codec.

    Warning: Do not register two different JSON codecs in the same process unless you intend for one to override the other.

    import (
    	_ "github.com/go-kratos/kratos/v3/encoding/json"
    	_ "github.com/go-kratos/kratos/v3/encoding/protojson"
    )
  5. Choose a JSON codec in Kratos v3

    main

    In v3, JSON codecs are split to avoid implicit behavior. You must explicitly import the codec you need:

    • Standard JSON: Use github.com/go-kratos/kratos/v3/encoding/json for standard library JSON semantics.
    • Protobuf JSON: Use github.com/go-kratos/kratos/v3/encoding/protojson for proto.Message values with protobuf JSON semantics.
    • v2 Compatibility: Use github.com/go-kratos/contrib/encoding/json/v3 if your service requires the v2 behavior where a single codec handles both ordinary JSON and protobuf messages.

    Warning: Do not register both the standard and protobuf JSON codecs in the same process unless you intend for the latter to replace the former.

    import (
    	_ "github.com/go-kratos/kratos/v3/encoding/json"
    	_ "github.com/go-kratos/kratos/v3/encoding/protojson"
    )
  6. Understand how Apollo Namespaces affect configuration keys

    main

    In the Apollo config center, the Namespace name becomes part of the configuration key path in Kratos.

    For example, if you load a namespace named application.json, the top-level key in your Kratos configuration object will be application. Any nested fields within that JSON file will be nested under that key.

    // If Apollo namespace is 'application.json'
    // and content is:
    {
      "http": {
        "address": ":8080"
      }
    }
    
    // The resulting Kratos config structure will be:
    {
      "application": {
        "http": {
          "address": ":8080"
        }
      }
    }
  7. Update JWT Middleware import path

    main

    JWT middleware has moved from the core module to contrib. If your project uses JWT, update your imports to use github.com/go-kratos/kratos/contrib/middleware/jwt/v3 and ensure you have github.com/golang-jwt/jwt/v5 in your dependencies.

    // v2
    import "github.com/go-kratos/kratos/v2/middleware/auth/jwt"
    
    // v3
    import "github.com/go-kratos/kratos/contrib/middleware/jwt/v3"
  8. Migrating from Kratos v2 to v3

    main
    Kratos v3 introduces changes to reduce core dependencies and make previously implicit behaviors explicit. Before upgrading production services, consult the official v2 to v3 migration guide located at docs/migration/v2-to-v3.md.
  9. Quick start with MCP Transport

    main

    To implement an MCP (Model Context Protocol) server in Kratos, use the github.com/go-kratos/kratos/contrib/transport/mcp/v3 module. This allows you to define tools using mcp-go and register them with a Kratos server.

    Key steps:

    1. Initialize a new MCP server using tm.NewServer with a name, version, address, and optional middleware.
    2. Define an MCP tool using mcp.NewTool with descriptions and argument schemas.
    3. Register a handler function for the tool using srv.AddTool(tool, handler).
    4. Wrap the server in a Kratos application using kratos.New and kratos.Server(srv).
    5. Run the application with app.Run().
    import(
        tm "github.com/go-kratos/kratos/contrib/transport/mcp/v3"
        mcp "github.com/mark3labs/mcp-go/mcp"
    )
    
    func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
        name, ok := request.Params.Arguments["name"].(string)
        if !ok {
            return nil, errors.New("name must be a string")
        }
        return mcp.NewToolResultText(fmt.Sprintf("Hello, %s!", name)), nil
    }
    
    func main() {
        // 1. Create the MCP server
        srv := tm.NewServer("kratos-mcp", "v1.0.0", tm.Address(":8000"), tm.Middleware(Health))
        
        // 2. Define the tool
        tool := mcp.NewTool("hello_world",
            mcp.WithDescription("Say hello to someone"),
            mcp.WithString("name",
                mcp.Required(),
                mcp.Description("Name of the person to greet"),
            ),
        )
        
        // 3. Add tool handler
        srv.AddTool(tool, helloHandler)
        
        // 4. Create Kratos application
        app := kratos.New(
            kratos.Name("kratos-app"),
            kratos.Server(srv),
        )
        
        // 5. Run
        if err := app.Run(); err != nil {
            panic(err)
        }
    }
  10. Apply Kubernetes ClusterRoleBinding via YAML

    main

    Instead of using the CLI, you can apply a YAML manifest to configure the ClusterRoleBinding for Kratos. Ensure the namespace in the subjects section matches the namespace where your service is running (e.g., mesh).

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: go-kratos:kube
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: view
    subjects:
    - kind: ServiceAccount
      name: default
      namespace: mesh