docs/migration/v2-to-v3.md
Kratos v3 cleans up historical coupling in the core framework and makes several previously implicit dependencies explicit. This guide summarizes the main upgrade work tracked in go-kratos/kratos#3820.
Update Kratos imports from github.com/go-kratos/kratos/v2 to github.com/go-kratos/kratos/v3.
// v2
import "github.com/go-kratos/kratos/v2"
// v3
import "github.com/go-kratos/kratos/v3"
Then refresh dependencies:
go get github.com/go-kratos/kratos/v3@latest
go mod tidy
Contrib modules also use /v3 import paths, for example github.com/go-kratos/kratos/contrib/middleware/jwt/v3.
In v2, encoding/json handled both ordinary Go JSON values and proto.Message values with protobuf JSON semantics. In v3, the core JSON codecs are split:
github.com/go-kratos/kratos/v3/encoding/json registers the standard-library JSON codec as json.github.com/go-kratos/kratos/v3/encoding/protojson registers the protobuf JSON codec as protojson.github.com/go-kratos/kratos/contrib/encoding/json/v3 keeps the v2-compatible json codec behavior for migration.New v3 code should prefer explicit imports:
import (
_ "github.com/go-kratos/kratos/v3/encoding/json"
_ "github.com/go-kratos/kratos/v3/encoding/protojson"
)
If a service depends on v2 behavior where the json codec also handles protobuf messages, use the contrib compatibility codec while migrating:
import _ "github.com/go-kratos/kratos/contrib/encoding/json/v3"
Do not register both JSON codecs for the same process unless you intentionally want the later import initialization to replace the earlier json codec registration.
Kratos v3 uses the standard-library log/slog APIs. Code that depends on log.Logger, log.Helper, log.Valuer, log.NewStdLogger, or trace/service helper fields should migrate to *slog.Logger, log.NewHandler, and log.NewLogger.
import (
"log/slog"
"os"
"github.com/go-kratos/kratos/v3/log"
)
logger := log.NewLogger(
slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
}),
log.WithFilter(log.FilterKey("password")),
).With(
slog.String("service.name", "helloworld"),
slog.String("service.version", "v1.0.0"),
)
log.SetDefault(logger)
Kratos application and middleware options now accept *slog.Logger.
app := kratos.New(
kratos.Name("helloworld"),
kratos.Logger(logger),
)
OpenTelemetry logging is provided by the contrib handler:
import (
"github.com/go-kratos/kratos/v3/log"
otel "github.com/go-kratos/kratos/contrib/otel/v3/log"
)
logger := log.NewLogger(otel.NewHandler("helloworld"))
JWT middleware moved out of core so projects only pull github.com/golang-jwt/jwt/v5 when they use JWT.
// v2
import "github.com/go-kratos/kratos/v2/middleware/auth/jwt"
// v3
import "github.com/go-kratos/kratos/contrib/middleware/jwt/v3"
After changing imports, run:
go get github.com/go-kratos/kratos/contrib/middleware/jwt/v3@latest
go mod tidy
The default circuit breaker no longer depends on github.com/go-kratos/aegis. Default usage does not require code changes:
handler := circuitbreaker.Client()(next)
If your service injects a custom Aegis breaker, add Aegis as an explicit dependency and adapt the injection point to WithBreakerFactory:
handler := circuitbreaker.Client(
circuitbreaker.WithBreakerFactory(func() circuitbreaker.CircuitBreaker {
return newBreaker()
}),
)(next)
The exported transport/http/binding package was removed. Generated _http.pb.go files do not need manual changes after regeneration.
For hand-written code:
binding.EncodeURL with http.BuildPath.transport/http.Context methods such as Bind, BindVars, BindQuery, and BindForm.encoding/form directly only for low-level query/form encoding needs.path := http.BuildPath("/v1/users/{id}", req)
After dependency and import updates, regenerate Kratos generated files:
go generate ./...
go mod tidy
Regeneration is especially important for services using generated HTTP clients or servers because v3 generated code no longer imports the removed HTTP binding package.
Run project tests and linters before shipping the migration:
go test ./...
go vet ./...
For this repository, use:
make test
make lint
/v2 to /v3.encoding/json, encoding/protojson, or the contrib compatibility JSON codec.log/slog-based APIs.contrib/middleware/jwt/v3.transport/http/binding usage.go mod tidy.