File: README.md
Translations: English | ็ฎไฝไธญๆ
Kratos
Kratos is a lightweight Go framework for building cloud-native microservices. It provides small, explicit APIs for transport, middleware, registry, configuration, logging, encoding, and code generation so applications can focus on business logic.
Features
- API-first development with Protobuf and generated HTTP/gRPC code.
- Unified transport layer for HTTP and gRPC.
- Composable middleware for recovery, logging, validation, tracing, metrics, auth, and more.
- Pluggable registry, configuration, and encoding components.
- Standard-library
log/slogbased logging with OpenTelemetry extensions in contrib packages. - Consistent metadata, errors, validation, OpenAPI, and code-generation workflows.
- A contrib ecosystem for optional integrations such as registries, config stores, middleware, encodings, and observability.
Installation
Requirements
- Go 1.25 or later
- protoc
- protoc-gen-go
Install the CLI
go install github.com/go-kratos/kratos/cmd/kratos/v3@latest
kratos upgradeCreate a Service
kratos new helloworld
cd helloworld
go mod tidy
kratos runVisit http://localhost:8000/helloworld/kratos after the service starts.
For a fuller generated service flow:
kratos proto add api/helloworld/helloworld.proto
kratos proto client api/helloworld/helloworld.proto
kratos proto server api/helloworld/helloworld.proto -t internal/service
go generate ./...
kratos runUsage Example
package main
import (
"github.com/go-kratos/kratos/v3"
"github.com/go-kratos/kratos/v3/transport/grpc"
"github.com/go-kratos/kratos/v3/transport/http"
)
func main() {
httpSrv := http.NewServer(http.Address(":8000"))
grpcSrv := grpc.NewServer(grpc.Address(":9000"))
app := kratos.New(
kratos.Name("helloworld"),
kratos.Version("v1.0.0"),
kratos.Server(httpSrv, grpcSrv),
)
if err := app.Run(); err != nil {
panic(err)
}
}v3 Migration
Kratos v3 reduces core dependencies and makes previously implicit behavior explicit. Review the v2 to v3 migration guide before upgrading production services.
Further Reading
Development
make test
make lintCommunity
Security
If you discover a security vulnerability in Kratos, please contact [email protected]. Security reports are handled privately before disclosure.
Contributors
Thank you for contributing to Kratos. The contribution guide is available in the Kratos documentation.
Acknowledgments
The following projects influenced Kratos design:
License
Kratos is open-sourced software licensed under the MIT license.
File: config/README.md
Config
kubernetes
go get -u github.com/go-kratos/kratos/contrib/config/kubernetes/v3apollo
go get -u github.com/go-kratos/kratos/contrib/config/apollo/v3etcd
go get -u github.com/go-kratos/kratos/contrib/config/etcd/v3nacos
go get -u github.com/go-kratos/kratos/contrib/config/nacos/v3File: contrib/transport/mcp/README.md
MCP Transport
This module implements the MCP server in Kratos based on mcp-go.
Quick start
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 Health(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/health/ready" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
srv := tm.NewServer("kratos-mcp", "v1.0.0", tm.Address(":8000"), tm.Middleware(Health))
tool := mcp.NewTool("hello_world",
mcp.WithDescription("Say hello to someone"),
mcp.WithString("name",
mcp.Required(),
mcp.Description("Name of the person to greet"),
),
)
// Add tool handler
srv.AddTool(tool, helloHandler)
// creates a kratos application
app := kratos.New(
kratos.Name("kratos-app"),
kratos.Server(srv),
)
if err := app.Run(); err != nil {
panic(err)
}
}File: contrib/registry/servicecomb/README.md
Servicecomb Registry
example
server
package main
import (
"log"
"github.com/go-chassis/sc-client"
"github.com/go-kratos/kratos/contrib/registry/servicecomb/v3"
"github.com/go-kratos/kratos/v3"
)
func main() {
c, err := sc.NewClient(sc.Options{
Endpoints: []string{"127.0.0.1:30100"},
})
if err != nil {
log.Panic(err)
}
r := servicecomb.NewRegistry(c)
app := kratos.New(
kratos.Name("helloServicecomb"),
kratos.Registrar(r),
)
if err := app.Run(); err != nil {
log.Fatal(err)
}
}client
package main
import (
"context"
"log"
"github.com/go-chassis/sc-client"
"github.com/go-kratos/kratos/contrib/registry/servicecomb/v3"
"github.com/go-kratos/kratos/v3/transport/grpc"
)
func main() {
c, err := sc.NewClient(sc.Options{
Endpoints: []string{"127.0.0.1:30100"},
})
if err != nil {
log.Panic(err)
}
r := servicecomb.NewRegistry(c)
ctx := context.Background()
conn, err := grpc.NewClient(
ctx,
grpc.WithEndpoint("discovery:///helloServicecomb"),
grpc.WithDiscovery(r),
)
if err != nil {
return
}
defer conn.Close()
}File: contrib/registry/nacos/README.md
Nacos Registry
example
server
package main
import (
"log"
"github.com/nacos-group/nacos-sdk-go/v2/clients"
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
"github.com/nacos-group/nacos-sdk-go/v2/vo"
"github.com/go-kratos/kratos/contrib/registry/nacos/v3"
"github.com/go-kratos/kratos/v3"
)
func main() {
sc := []constant.ServerConfig{
*constant.NewServerConfig("127.0.0.1", 8848),
}
client, err := clients.NewNamingClient(
vo.NacosClientParam{
ServerConfigs: sc,
},
)
if err != nil {
log.Panic(err)
}
r := nacos.New(client)
// server
app := kratos.New(
kratos.Name("helloworld"),
kratos.Registrar(r),
)
if err := app.Run(); err != nil {
log.Fatal(err)
}
}client
package main
import (
"context"
"log"
"github.com/nacos-group/nacos-sdk-go/v2/clients"
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
"github.com/nacos-group/nacos-sdk-go/v2/vo"
"github.com/go-kratos/kratos/contrib/registry/nacos/v3"
"github.com/go-kratos/kratos/v3/transport/grpc"
)
func main() {
cc := constant.ClientConfig{
NamespaceId: "public",
TimeoutMs: 5000,
}
client, err := clients.NewNamingClient(
vo.NacosClientParam{
ClientConfig: &cc,
},
)
if err != nil {
log.Panic(err)
}
r := nacos.New(client)
// client
conn, err := grpc.NewClient(
context.Background(),
grpc.WithEndpoint("discovery:///helloworld"),
grpc.WithDiscovery(r),
)
defer conn.Close()
}File: contrib/registry/discovery/README.md
Discovery Registry
This module implements a registry.Registrar and registry.Discovery interface in kratos based bilibili/discovery.
Quick Start
Register a service
import (
"github.com/go-kratos/kratos/contrib/registry/discovery/v3"
)
func main() {
// initialize a registry
r := discovery.New(&discovery.Config{
Nodes: []string{"0.0.0.0:7171"},
Env: "dev",
Region: "sh1",
Zone: "zone1",
Host: "hostname",
})
// construct srv instance
// ...
app := kratos.New(
kratos.Name("helloworld"),
kratos.Server(
httpSrv,
grpcSrv,
),
kratos.Metadata(map[string]string{"color": "gray"}),
// use Registrar
kratos.Registrar(r),
)
if err := app.Run(); err != nil {
log.Fatal(err)
}
}Discover a service
import (
"github.com/go-kratos/kratos/contrib/registry/discovery/v3"
"github.com/go-kratos/kratos/v3/transport/grpc"
)
func main() {
// initialize a discovery
r := discovery.New(&discovery.Config{
Nodes: []string{"0.0.0.0:7171"},
Env: "dev",
Region: "sh1",
Zone: "zone1",
Host: "localhost",
}, nil)
conn, err := grpc.NewClient(
context.Background(),
grpc.WithEndpoint("discovery:///appid"),
// use discovery
grpc.WithDiscovery(r),
)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
// request and log
}Config explain
type Config struct {
Nodes []string // discovery nodes address
Region string // region of the service, sh
Zone string // zone of region, sh001
Env string // env of service, dev, prod and etc
Host string // hostname of service
}References
File: contrib/opensergo/README.md
OpenSergo
Usage
osServer, err := opensergo.New(opensergo.WithEndpoint("localhost:9090"))
if err != nil {
panic("init opensergo error")
}
s := &server{}
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
recovery.Recovery(),
),
)
helloworld.RegisterGreeterServer(grpcSrv, s)
app := kratos.New(
kratos.Name(Name),
kratos.Server(
grpcSrv,
),
)
osServer.ReportMetadata(context.Background(), app)
if err := app.Run(); err != nil {
log.Fatal(err)
}File: contrib/middleware/validate/README.md
Validator Middleware for Kratos Project
This module provides a middleware for Kratos to validate request parameters, using schema defined in .proto files.
There used to be a middleware named Validator in Kratos, which calls the generated validation functions
from PGV at runtime. Since PGV has been
in maintenance, and
recommend using protovalidate as an alternative.
That's why we provide a new middleware that uses the schema definitions and validation functions provided by
protovalidate.
protovalidate no longer requires code generation at build time, but for compatibility with existing Kratos
projects, we enable the legacy mode of protovalidate. For most users, no changes are needed to existing code. But for
users who have manually implemented the Validator interface, you need to migrate the relevant implementation yourself.
File: contrib/errortracker/sentry/README.md
Sentry middleware for Kratos
This middleware helps you to catch panics and report them to sentry
Quick Start
You could check the full demo in example folder.
// Step 1:
// init sentry in the entry of your application
import "github.com/getsentry/sentry-go"
sentry.Init(sentry.ClientOptions{
Dsn: "<your dsn>",
AttachStacktrace: true, // recommended
})
// Step 2:
// set middleware
import (
"context"
ksentry "github.com/go-kratos/kratos/contrib/errortracker/sentry/v3"
"github.com/go-kratos/kratos/contrib/otel/v3/tracing"
)
// for HTTP server, new HTTP server with sentry middleware options
var opts = []http.ServerOption{
http.Middleware(
recovery.Recovery(),
tracing.Server(),
ksentry.Server(
ksentry.WithTags(map[string]string{
"tag": "some-custom-constant-tag",
}),
ksentry.WithContextTags(func(ctx context.Context) map[string]string {
return map[string]string{"trace_id": tracing.TraceID(ctx)}
}),
), // must after Recovery middleware, because of the exiting order will be reversed
logging.Server(logger),
),
}
// for gRPC server, new gRPC server with sentry middleware options
var opts = []grpc.ServerOption{
grpc.Middleware(
recovery.Recovery(),
tracing.Server(),
ksentry.Server(
ksentry.WithTags(map[string]string{
"tag": "some-custom-constant-tag",
}),
ksentry.WithContextTags(func(ctx context.Context) map[string]string {
return map[string]string{"trace_id": tracing.TraceID(ctx)}
}),
), // must after Recovery middleware, because of the exiting order will be reversed
logging.Server(logger),
),
}
// Then, the framework will report events to Sentry when your trigger panics.
// Or your can push events to Sentry manually