Repository: go-kratos/kratos
Pull request #1028 (2021-06-10 11:57:14)

Feat/uni transport
1、去掉了 transport 暴露的 Request/Response，保证 middleware 不乱修改；
2、添加了 Metadata，以及实现 tracing carrier，支持 incoming/outgoing；
3、transport 统一去掉了 ServerInfo，换成 middleware WithMethod，用于得到是那个 service method；
4、httpclient 少量的修正，默认传 invoke 参数；
5、抽象了 Transport 接口，提交 Method、Metadata 操作；


Patch:
diff --git a/api/metadata/metadata.pb.go b/api/metadata/metadata.pb.go
index a5e2067b..3f8d3bcd 100644
--- a/api/metadata/metadata.pb.go
+++ b/api/metadata/metadata.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
+// 	protoc        v3.15.7
 // source: metadata.proto
 
 package metadata
diff --git a/api/metadata/metadata_http.pb.go b/api/metadata/metadata_http.pb.go
index 86e1dbc4..e19b1592 100644
--- a/api/metadata/metadata_http.pb.go
+++ b/api/metadata/metadata_http.pb.go
@@ -4,6 +4,8 @@ package metadata
 
 import (
 	context "context"
+	middleware "github.com/go-kratos/kratos/v2/middleware"
+	transport "github.com/go-kratos/kratos/v2/transport"
 	http1 "github.com/go-kratos/kratos/v2/transport/http"
 	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
 	mux "github.com/gorilla/mux"
@@ -14,7 +16,9 @@ import (
 // is compatible with the kratos package it is being compiled against.
 var _ = new(http.Request)
 var _ = new(context.Context)
-var _ = binding.MapProto
+var _ = new(middleware.Middleware)
+var _ = new(transport.Transporter)
+var _ = binding.BindVars
 var _ = mux.NewRouter
 
 const _ = http1.SupportPackageIsVersion1
@@ -45,7 +49,9 @@ func NewMetadataHandler(srv MetadataHandler, opts ...http1.HandleOption) http.Ha
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/kratos.api.Metadata/ListServices")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -74,7 +80,9 @@ func NewMetadataHandler(srv MetadataHandler, opts ...http1.HandleOption) http.Ha
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/kratos.api.Metadata/GetServiceDesc")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -102,26 +110,22 @@ func NewMetadataHTTPClient(client *http1.Client) MetadataHTTPClient {
 	return &MetadataHTTPClientImpl{client}
 }
 
-func (c *MetadataHTTPClientImpl) GetServiceDesc(ctx context.Context, in *GetServiceDescRequest, opts ...http1.CallOption) (out *GetServiceDescReply, err error) {
+func (c *MetadataHTTPClientImpl) GetServiceDesc(ctx context.Context, in *GetServiceDescRequest, opts ...http1.CallOption) (*GetServiceDescReply, error) {
+	var out GetServiceDescReply
 	path := binding.EncodePath("GET", "/services/{name}", in)
-	out = &GetServiceDescReply{}
+	opts = append(opts, http1.Method("/kratos.api.Metadata/GetServiceDesc"))
 
-	err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("GET"), http1.PathPattern("/services/{name}"))
+	err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
 
-func (c *MetadataHTTPClientImpl) ListServices(ctx context.Context, in *ListServicesRequest, opts ...http1.CallOption) (out *ListServicesReply, err error) {
+func (c *MetadataHTTPClientImpl) ListServices(ctx context.Context, in *ListServicesRequest, opts ...http1.CallOption) (*ListServicesReply, error) {
+	var out ListServicesReply
 	path := binding.EncodePath("GET", "/services", in)
-	out = &ListServicesReply{}
+	opts = append(opts, http1.Method("/kratos.api.Metadata/ListServices"))
 
-	err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("GET"), http1.PathPattern("/services"))
+	err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
diff --git a/cmd/protoc-gen-go-http/go.mod b/cmd/protoc-gen-go-http/go.mod
index 601d5caf..db986649 100644
--- a/cmd/protoc-gen-go-http/go.mod
+++ b/cmd/protoc-gen-go-http/go.mod
@@ -6,4 +6,3 @@ require (
 	google.golang.org/genproto v0.0.0-20210521181308-5ccab8a35a9a
 	google.golang.org/protobuf v1.26.0
 )
-
diff --git a/cmd/protoc-gen-go-http/http.go b/cmd/protoc-gen-go-http/http.go
index a277ba56..97148677 100644
--- a/cmd/protoc-gen-go-http/http.go
+++ b/cmd/protoc-gen-go-http/http.go
@@ -10,11 +10,13 @@ import (
 )
 
 const (
-	contextPackage   = protogen.GoImportPath("context")
-	httpPackage      = protogen.GoImportPath("net/http")
-	muxPackage       = protogen.GoImportPath("github.com/gorilla/mux")
-	transportPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http")
-	bindingPackage   = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http/binding")
+	contextPackage       = protogen.GoImportPath("context")
+	httpPackage          = protogen.GoImportPath("net/http")
+	muxPackage           = protogen.GoImportPath("github.com/gorilla/mux")
+	middlewarePackage    = protogen.GoImportPath("github.com/go-kratos/kratos/v2/middleware")
+	transportHTTPPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http")
+	bindingPackage       = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http/binding")
+	transportPackage     = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport")
 )
 
 var methodSets = make(map[string]int)
@@ -43,9 +45,11 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.
 	g.P("// is compatible with the kratos package it is being compiled against.")
 	g.P("var _ = new(", httpPackage.Ident("Request"), ")")
 	g.P("var _ = new(", contextPackage.Ident("Context"), ")")
-	g.P("var _ = ", bindingPackage.Ident("MapProto"))
+	g.P("var _ = new(", middlewarePackage.Ident("Middleware"), ")")
+	g.P("var _ = new(", transportPackage.Ident("Transporter"), ")")
+	g.P("var _ = ", bindingPackage.Ident("BindVars"))
 	g.P("var _ = ", muxPackage.Ident("NewRouter"))
-	g.P("const _ = ", transportPackage.Ident("SupportPackageIsVersion1"))
+	g.P("const _ = ", transportHTTPPackage.Ident("SupportPackageIsVersion1"))
 	g.P()
 
 	for _, service := range file.Services {
diff --git a/cmd/protoc-gen-go-http/template.go b/cmd/protoc-gen-go-http/template.go
index af61955c..37245363 100644
--- a/cmd/protoc-gen-go-http/template.go
+++ b/cmd/protoc-gen-go-http/template.go
@@ -7,6 +7,8 @@ import (
 )
 
 var httpTemplate = `
+{{$svrType := .ServiceType}}
+{{$svrName := .ServiceName}}
 type {{.ServiceType}}Handler interface {
 {{range .MethodSets}}
 	{{.Name}}(context.Context, *{{.Request}}) (*{{.Reply}}, error)
@@ -38,7 +40,9 @@ func New{{.ServiceType}}Handler(srv {{.ServiceType}}Handler, opts ...http1.Handl
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx,"/{{$svrName}}/{{.Name}}")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -65,19 +69,18 @@ type {{.ServiceType}}HTTPClientImpl struct{
 func New{{.ServiceType}}HTTPClient (client *http1.Client) {{.ServiceType}}HTTPClient {
 	return &{{.ServiceType}}HTTPClientImpl{client}
 }
-	
-{{$svrType := .ServiceType}}
-{{$svrName := .ServiceName}}
+
 {{range .MethodSets}}
-func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http1.CallOption) (out *{{.Reply}}, err error) {
+func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http1.CallOption) (*{{.Reply}}, error) {
+	var out {{.Reply}}
 	path := binding.EncodePath("{{.Method}}", "{{.Path}}", in)
-	out = &{{.Reply}}{}
+	opts = append(opts, http1.Method("/{{$svrName}}/{{.Name}}"))
 	{{if .HasBody }}
-	err = c.cc.Invoke(ctx, path, in{{.Body}}, &out{{.ResponseBody}}, http1.Method("{{.Method}}"), http1.PathPattern("{{.Path}}"))
+	err := c.cc.Invoke(ctx, "{{.Method}}", path, in{{.Body}}, &out{{.ResponseBody}}, opts...)
 	{{else}} 
-	err = c.cc.Invoke(ctx, path, nil, &out{{.ResponseBody}}, http1.Method("{{.Method}}"), http1.PathPattern("{{.Path}}"))
+	err := c.cc.Invoke(ctx, "{{.Method}}", path, nil, &out{{.ResponseBody}}, opts...)
 	{{end}}
-	return 
+	return &out, err
 }
 {{end}}
 `
diff --git a/errors/errors.pb.go b/errors/errors.pb.go
index 4f99f518..16eb19d6 100644
--- a/errors/errors.pb.go
+++ b/errors/errors.pb.go
@@ -1,15 +1,15 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.13.0
+// 	protoc        v3.15.7
 // source: errors.proto
 
 package errors
 
 import (
-	descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	descriptorpb "google.golang.org/protobuf/types/descriptorpb"
 	reflect "reflect"
 	sync "sync"
 )
@@ -94,7 +94,7 @@ func (x *Error) GetMetadata() map[string]string {
 
 var file_errors_proto_extTypes = []protoimpl.ExtensionInfo{
 	{
-		ExtendedType:  (*descriptor.EnumOptions)(nil),
+		ExtendedType:  (*descriptorpb.EnumOptions)(nil),
 		ExtensionType: (*int32)(nil),
 		Field:         1108,
 		Name:          "errors.default_code",
@@ -102,7 +102,7 @@ var file_errors_proto_extTypes = []protoimpl.ExtensionInfo{
 		Filename:      "errors.proto",
 	},
 	{
-		ExtendedType:  (*descriptor.EnumValueOptions)(nil),
+		ExtendedType:  (*descriptorpb.EnumValueOptions)(nil),
 		ExtensionType: (*int32)(nil),
 		Field:         1109,
 		Name:          "errors.code",
@@ -111,13 +111,13 @@ var file_errors_proto_extTypes = []protoimpl.ExtensionInfo{
 	},
 }
 
-// Extension fields to descriptor.EnumOptions.
+// Extension fields to descriptorpb.EnumOptions.
 var (
 	// optional int32 default_code = 1108;
 	E_DefaultCode = &file_errors_proto_extTypes[0]
 )
 
-// Extension fields to descriptor.EnumValueOptions.
+// Extension fields to descriptorpb.EnumValueOptions.
 var (
 	// optional int32 code = 1109;
 	E_Code = &file_errors_proto_extTypes[1]
@@ -172,10 +172,10 @@ func file_errors_proto_rawDescGZIP() []byte {
 
 var file_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
 var file_errors_proto_goTypes = []interface{}{
-	(*Error)(nil),                       // 0: errors.Error
-	nil,                                 // 1: errors.Error.MetadataEntry
-	(*descriptor.EnumOptions)(nil),      // 2: google.protobuf.EnumOptions
-	(*descriptor.EnumValueOptions)(nil), // 3: google.protobuf.EnumValueOptions
+	(*Error)(nil),                         // 0: errors.Error
+	nil,                                   // 1: errors.Error.MetadataEntry
+	(*descriptorpb.EnumOptions)(nil),      // 2: google.protobuf.EnumOptions
+	(*descriptorpb.EnumValueOptions)(nil), // 3: google.protobuf.EnumValueOptions
 }
 var file_errors_proto_depIdxs = []int32{
 	1, // 0: errors.Error.metadata:type_name -> errors.Error.MetadataEntry
diff --git a/examples/blog/Makefile b/examples/blog/Makefile
index 8c981276..16bedc4d 100644
--- a/examples/blog/Makefile
+++ b/examples/blog/Makefile
@@ -33,6 +33,15 @@ http:
            --go-http_out=paths=source_relative:. \
            $(API_PROTO_FILES)
 
+.PHONY: errors
+# generate errors code
+errors:
+	protoc --proto_path=. \
+           --proto_path=./third_party \
+           --go_out=paths=source_relative:. \
+           --go-errors_out=paths=source_relative:. \
+           $(API_PROTO_FILES)
+
 .PHONY: proto
 # generate internal proto
 proto:
@@ -72,6 +81,7 @@ all:
 	make grpc;
 	make http;
 	make proto;
+	make errors;
 	make swagger;
 	make build;
 	make test;
diff --git a/examples/blog/api/blog/v1/blog.pb.go b/examples/blog/api/blog/v1/blog.pb.go
index 92a3faab..91b80a81 100644
--- a/examples/blog/api/blog/v1/blog.pb.go
+++ b/examples/blog/api/blog/v1/blog.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
-// source: api/blog/v1/blog.proto
+// 	protoc        v3.15.7
+// source: blog/api/blog/v1/blog.proto
 
 package v1
 
@@ -36,7 +36,7 @@ type Article struct {
 func (x *Article) Reset() {
 	*x = Article{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[0]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -49,7 +49,7 @@ func (x *Article) String() string {
 func (*Article) ProtoMessage() {}
 
 func (x *Article) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[0]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -62,7 +62,7 @@ func (x *Article) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Article.ProtoReflect.Descriptor instead.
 func (*Article) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{0}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *Article) GetId() int64 {
@@ -105,7 +105,7 @@ type CreateArticleRequest struct {
 func (x *CreateArticleRequest) Reset() {
 	*x = CreateArticleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[1]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -118,7 +118,7 @@ func (x *CreateArticleRequest) String() string {
 func (*CreateArticleRequest) ProtoMessage() {}
 
 func (x *CreateArticleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[1]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -131,7 +131,7 @@ func (x *CreateArticleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateArticleRequest.ProtoReflect.Descriptor instead.
 func (*CreateArticleRequest) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{1}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *CreateArticleRequest) GetTitle() string {
@@ -159,7 +159,7 @@ type CreateArticleReply struct {
 func (x *CreateArticleReply) Reset() {
 	*x = CreateArticleReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[2]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -172,7 +172,7 @@ func (x *CreateArticleReply) String() string {
 func (*CreateArticleReply) ProtoMessage() {}
 
 func (x *CreateArticleReply) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[2]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -185,7 +185,7 @@ func (x *CreateArticleReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateArticleReply.ProtoReflect.Descriptor instead.
 func (*CreateArticleReply) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{2}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *CreateArticleReply) GetArticle() *Article {
@@ -208,7 +208,7 @@ type UpdateArticleRequest struct {
 func (x *UpdateArticleRequest) Reset() {
 	*x = UpdateArticleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[3]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -221,7 +221,7 @@ func (x *UpdateArticleRequest) String() string {
 func (*UpdateArticleRequest) ProtoMessage() {}
 
 func (x *UpdateArticleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[3]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -234,7 +234,7 @@ func (x *UpdateArticleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateArticleRequest.ProtoReflect.Descriptor instead.
 func (*UpdateArticleRequest) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{3}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *UpdateArticleRequest) GetId() int64 {
@@ -269,7 +269,7 @@ type UpdateArticleReply struct {
 func (x *UpdateArticleReply) Reset() {
 	*x = UpdateArticleReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[4]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -282,7 +282,7 @@ func (x *UpdateArticleReply) String() string {
 func (*UpdateArticleReply) ProtoMessage() {}
 
 func (x *UpdateArticleReply) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[4]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -295,7 +295,7 @@ func (x *UpdateArticleReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateArticleReply.ProtoReflect.Descriptor instead.
 func (*UpdateArticleReply) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{4}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{4}
 }
 
 func (x *UpdateArticleReply) GetArticle() *Article {
@@ -316,7 +316,7 @@ type DeleteArticleRequest struct {
 func (x *DeleteArticleRequest) Reset() {
 	*x = DeleteArticleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[5]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -329,7 +329,7 @@ func (x *DeleteArticleRequest) String() string {
 func (*DeleteArticleRequest) ProtoMessage() {}
 
 func (x *DeleteArticleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[5]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -342,7 +342,7 @@ func (x *DeleteArticleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteArticleRequest.ProtoReflect.Descriptor instead.
 func (*DeleteArticleRequest) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{5}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *DeleteArticleRequest) GetId() int64 {
@@ -361,7 +361,7 @@ type DeleteArticleReply struct {
 func (x *DeleteArticleReply) Reset() {
 	*x = DeleteArticleReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[6]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -374,7 +374,7 @@ func (x *DeleteArticleReply) String() string {
 func (*DeleteArticleReply) ProtoMessage() {}
 
 func (x *DeleteArticleReply) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[6]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -387,7 +387,7 @@ func (x *DeleteArticleReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteArticleReply.ProtoReflect.Descriptor instead.
 func (*DeleteArticleReply) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{6}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{6}
 }
 
 type GetArticleRequest struct {
@@ -401,7 +401,7 @@ type GetArticleRequest struct {
 func (x *GetArticleRequest) Reset() {
 	*x = GetArticleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[7]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -414,7 +414,7 @@ func (x *GetArticleRequest) String() string {
 func (*GetArticleRequest) ProtoMessage() {}
 
 func (x *GetArticleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[7]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -427,7 +427,7 @@ func (x *GetArticleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetArticleRequest.ProtoReflect.Descriptor instead.
 func (*GetArticleRequest) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{7}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{7}
 }
 
 func (x *GetArticleRequest) GetId() int64 {
@@ -448,7 +448,7 @@ type GetArticleReply struct {
 func (x *GetArticleReply) Reset() {
 	*x = GetArticleReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[8]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[8]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -461,7 +461,7 @@ func (x *GetArticleReply) String() string {
 func (*GetArticleReply) ProtoMessage() {}
 
 func (x *GetArticleReply) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[8]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[8]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -474,7 +474,7 @@ func (x *GetArticleReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetArticleReply.ProtoReflect.Descriptor instead.
 func (*GetArticleReply) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{8}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{8}
 }
 
 func (x *GetArticleReply) GetArticle() *Article {
@@ -493,7 +493,7 @@ type ListArticleRequest struct {
 func (x *ListArticleRequest) Reset() {
 	*x = ListArticleRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[9]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[9]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -506,7 +506,7 @@ func (x *ListArticleRequest) String() string {
 func (*ListArticleRequest) ProtoMessage() {}
 
 func (x *ListArticleRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[9]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[9]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -519,7 +519,7 @@ func (x *ListArticleRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListArticleRequest.ProtoReflect.Descriptor instead.
 func (*ListArticleRequest) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{9}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{9}
 }
 
 type ListArticleReply struct {
@@ -533,7 +533,7 @@ type ListArticleReply struct {
 func (x *ListArticleReply) Reset() {
 	*x = ListArticleReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_api_blog_v1_blog_proto_msgTypes[10]
+		mi := &file_blog_api_blog_v1_blog_proto_msgTypes[10]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -546,7 +546,7 @@ func (x *ListArticleReply) String() string {
 func (*ListArticleReply) ProtoMessage() {}
 
 func (x *ListArticleReply) ProtoReflect() protoreflect.Message {
-	mi := &file_api_blog_v1_blog_proto_msgTypes[10]
+	mi := &file_blog_api_blog_v1_blog_proto_msgTypes[10]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -559,7 +559,7 @@ func (x *ListArticleReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListArticleReply.ProtoReflect.Descriptor instead.
 func (*ListArticleReply) Descriptor() ([]byte, []int) {
-	return file_api_blog_v1_blog_proto_rawDescGZIP(), []int{10}
+	return file_blog_api_blog_v1_blog_proto_rawDescGZIP(), []int{10}
 }
 
 func (x *ListArticleReply) GetResults() []*Article {
@@ -569,113 +569,114 @@ func (x *ListArticleReply) GetResults() []*Article {
 	return nil
 }
 
-var File_api_blog_v1_blog_proto protoreflect.FileDescriptor
-
-var file_api_blog_v1_blog_proto_rawDesc = []byte{
-	0x0a, 0x16, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x6c,
-	0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70,
-	0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61,
-	0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x07,
-	0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a,
-	0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6b, 0x65, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6b, 0x65, 0x22, 0x51, 0x0a, 0x14, 0x43,
-	0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04, 0x10, 0x05, 0x18, 0x32, 0x52, 0x05, 0x74,
-	0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x44,
-	0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52,
-	0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69,
-	0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x41, 0x72, 0x74,
-	0x69, 0x63, 0x6c, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72,
-	0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x02,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x22, 0x02, 0x20,
-	0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04, 0x10, 0x05, 0x18, 0x32, 0x52,
-	0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x22, 0x44, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
-	0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x41,
-	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x22, 0x26, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+var File_blog_api_blog_v1_blog_proto protoreflect.FileDescriptor
+
+var file_blog_api_blog_v1_blog_proto_rawDesc = []byte{
+	0x0a, 0x1b, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f,
+	0x76, 0x31, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x62,
+	0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
+	0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x22, 0x5d, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05,
+	0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74,
+	0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04,
+	0x6c, 0x69, 0x6b, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6b, 0x65,
+	0x22, 0x51, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04, 0x10, 0x05,
+	0x18, 0x32, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x22, 0x44, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74,
+	0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x41, 0x72, 0x74,
+	0x69, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x6c, 0x6f,
+	0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
+	0x52, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x42, 0x07, 0xfa,
+	0x42, 0x04, 0x22, 0x02, 0x20, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x05, 0x74, 0x69,
+	0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04,
+	0x10, 0x05, 0x18, 0x32, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x44, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41,
+	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x41,
+	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62,
+	0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63,
+	0x6c, 0x65, 0x52, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x22, 0x26, 0x0a, 0x14, 0x44,
+	0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x02, 0x69, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74,
+	0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, 0x74,
 	0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e,
-	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x14,
-	0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52,
-	0x65, 0x70, 0x6c, 0x79, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63,
-	0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x41, 0x0a, 0x0f, 0x47, 0x65, 0x74,
-	0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07,
-	0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
-	0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69,
-	0x63, 0x6c, 0x65, 0x52, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x22, 0x14, 0x0a, 0x12,
-	0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x22, 0x42, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
-	0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
-	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x72,
-	0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x32, 0xa7, 0x04, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x67, 0x53,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69,
-	0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x62, 0x6c, 0x6f,
-	0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41,
-	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x17, 0x82, 0xd3, 0xe4,
-	0x93, 0x02, 0x11, 0x22, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
-	0x2f, 0x3a, 0x01, 0x2a, 0x12, 0x70, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72,
-	0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69,
-	0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e,
-	0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74,
-	0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02,
-	0x15, 0x1a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x7b,
-	0x69, 0x64, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x6d, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
-	0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69,
-	0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x62, 0x6c, 0x6f,
-	0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41,
-	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4,
-	0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
-	0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69,
-	0x63, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
-	0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
-	0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c,
-	0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61,
-	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x63, 0x0a, 0x0b, 0x4c,
-	0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x62, 0x6c, 0x6f,
-	0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74,
-	0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x62, 0x6c,
-	0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72,
-	0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93,
-	0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f,
-	0x42, 0x44, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x50,
-	0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f,
-	0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65,
-	0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69,
-	0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x41,
+	0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c,
+	0x79, 0x12, 0x2e, 0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
+	0x2e, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
+	0x65, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x42, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x41,
+	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62,
+	0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x63,
+	0x6c, 0x65, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x32, 0xa7, 0x04, 0x0a, 0x0b,
+	0x42, 0x6c, 0x6f, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0d, 0x43,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x21, 0x2e, 0x62,
+	0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x1f, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79,
+	0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x22, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72,
+	0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x3a, 0x01, 0x2a, 0x12, 0x70, 0x0a, 0x0d, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x21, 0x2e, 0x62, 0x6c, 0x6f,
+	0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41,
+	0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e,
+	0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b,
+	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x1a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69,
+	0x63, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x6d, 0x0a, 0x0d, 0x44,
+	0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x21, 0x2e, 0x62,
+	0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
+	0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x1f, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65,
+	0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79,
+	0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72,
+	0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0a, 0x47, 0x65,
+	0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c,
+	0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10,
+	0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d,
+	0x12, 0x63, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12,
+	0x1f, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
+	0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x1d, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c,
+	0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,
+	0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x72, 0x74,
+	0x69, 0x63, 0x6c, 0x65, 0x2f, 0x42, 0x44, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x76, 0x31, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61,
+	0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f,
+	0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
 }
 
 var (
-	file_api_blog_v1_blog_proto_rawDescOnce sync.Once
-	file_api_blog_v1_blog_proto_rawDescData = file_api_blog_v1_blog_proto_rawDesc
+	file_blog_api_blog_v1_blog_proto_rawDescOnce sync.Once
+	file_blog_api_blog_v1_blog_proto_rawDescData = file_blog_api_blog_v1_blog_proto_rawDesc
 )
 
-func file_api_blog_v1_blog_proto_rawDescGZIP() []byte {
-	file_api_blog_v1_blog_proto_rawDescOnce.Do(func() {
-		file_api_blog_v1_blog_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_blog_v1_blog_proto_rawDescData)
+func file_blog_api_blog_v1_blog_proto_rawDescGZIP() []byte {
+	file_blog_api_blog_v1_blog_proto_rawDescOnce.Do(func() {
+		file_blog_api_blog_v1_blog_proto_rawDescData = protoimpl.X.CompressGZIP(file_blog_api_blog_v1_blog_proto_rawDescData)
 	})
-	return file_api_blog_v1_blog_proto_rawDescData
+	return file_blog_api_blog_v1_blog_proto_rawDescData
 }
 
-var file_api_blog_v1_blog_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
-var file_api_blog_v1_blog_proto_goTypes = []interface{}{
+var file_blog_api_blog_v1_blog_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
+var file_blog_api_blog_v1_blog_proto_goTypes = []interface{}{
 	(*Article)(nil),              // 0: blog.api.v1.Article
 	(*CreateArticleRequest)(nil), // 1: blog.api.v1.CreateArticleRequest
 	(*CreateArticleReply)(nil),   // 2: blog.api.v1.CreateArticleReply
@@ -688,7 +689,7 @@ var file_api_blog_v1_blog_proto_goTypes = []interface{}{
 	(*ListArticleRequest)(nil),   // 9: blog.api.v1.ListArticleRequest
 	(*ListArticleReply)(nil),     // 10: blog.api.v1.ListArticleReply
 }
-var file_api_blog_v1_blog_proto_depIdxs = []int32{
+var file_blog_api_blog_v1_blog_proto_depIdxs = []int32{
 	0,  // 0: blog.api.v1.CreateArticleReply.Article:type_name -> blog.api.v1.Article
 	0,  // 1: blog.api.v1.UpdateArticleReply.Article:type_name -> blog.api.v1.Article
 	0,  // 2: blog.api.v1.GetArticleReply.Article:type_name -> blog.api.v1.Article
@@ -710,13 +711,13 @@ var file_api_blog_v1_blog_proto_depIdxs = []int32{
 	0,  // [0:4] is the sub-list for field type_name
 }
 
-func init() { file_api_blog_v1_blog_proto_init() }
-func file_api_blog_v1_blog_proto_init() {
-	if File_api_blog_v1_blog_proto != nil {
+func init() { file_blog_api_blog_v1_blog_proto_init() }
+func file_blog_api_blog_v1_blog_proto_init() {
+	if File_blog_api_blog_v1_blog_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_api_blog_v1_blog_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Article); i {
 			case 0:
 				return &v.state
@@ -728,7 +729,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateArticleRequest); i {
 			case 0:
 				return &v.state
@@ -740,7 +741,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*CreateArticleReply); i {
 			case 0:
 				return &v.state
@@ -752,7 +753,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateArticleRequest); i {
 			case 0:
 				return &v.state
@@ -764,7 +765,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*UpdateArticleReply); i {
 			case 0:
 				return &v.state
@@ -776,7 +777,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteArticleRequest); i {
 			case 0:
 				return &v.state
@@ -788,7 +789,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DeleteArticleReply); i {
 			case 0:
 				return &v.state
@@ -800,7 +801,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetArticleRequest); i {
 			case 0:
 				return &v.state
@@ -812,7 +813,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetArticleReply); i {
 			case 0:
 				return &v.state
@@ -824,7 +825,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListArticleRequest); i {
 			case 0:
 				return &v.state
@@ -836,7 +837,7 @@ func file_api_blog_v1_blog_proto_init() {
 				return nil
 			}
 		}
-		file_api_blog_v1_blog_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_api_blog_v1_blog_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ListArticleReply); i {
 			case 0:
 				return &v.state
@@ -853,18 +854,18 @@ func file_api_blog_v1_blog_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_api_blog_v1_blog_proto_rawDesc,
+			RawDescriptor: file_blog_api_blog_v1_blog_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   11,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
-		GoTypes:           file_api_blog_v1_blog_proto_goTypes,
-		DependencyIndexes: file_api_blog_v1_blog_proto_depIdxs,
-		MessageInfos:      file_api_blog_v1_blog_proto_msgTypes,
+		GoTypes:           file_blog_api_blog_v1_blog_proto_goTypes,
+		DependencyIndexes: file_blog_api_blog_v1_blog_proto_depIdxs,
+		MessageInfos:      file_blog_api_blog_v1_blog_proto_msgTypes,
 	}.Build()
-	File_api_blog_v1_blog_proto = out.File
-	file_api_blog_v1_blog_proto_rawDesc = nil
-	file_api_blog_v1_blog_proto_goTypes = nil
-	file_api_blog_v1_blog_proto_depIdxs = nil
+	File_blog_api_blog_v1_blog_proto = out.File
+	file_blog_api_blog_v1_blog_proto_rawDesc = nil
+	file_blog_api_blog_v1_blog_proto_goTypes = nil
+	file_blog_api_blog_v1_blog_proto_depIdxs = nil
 }
diff --git a/examples/blog/api/blog/v1/blog_grpc.pb.go b/examples/blog/api/blog/v1/blog_grpc.pb.go
index 433c6e1c..40c82d58 100644
--- a/examples/blog/api/blog/v1/blog_grpc.pb.go
+++ b/examples/blog/api/blog/v1/blog_grpc.pb.go
@@ -241,5 +241,5 @@ var BlogService_ServiceDesc = grpc.ServiceDesc{
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "api/blog/v1/blog.proto",
+	Metadata: "blog/api/blog/v1/blog.proto",
 }
diff --git a/examples/blog/api/blog/v1/blog_http.pb.go b/examples/blog/api/blog/v1/blog_http.pb.go
index e73adf3c..4a0ceff2 100644
--- a/examples/blog/api/blog/v1/blog_http.pb.go
+++ b/examples/blog/api/blog/v1/blog_http.pb.go
@@ -4,6 +4,8 @@ package v1
 
 import (
 	context "context"
+	middleware "github.com/go-kratos/kratos/v2/middleware"
+	transport "github.com/go-kratos/kratos/v2/transport"
 	http1 "github.com/go-kratos/kratos/v2/transport/http"
 	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
 	mux "github.com/gorilla/mux"
@@ -14,7 +16,9 @@ import (
 // is compatible with the kratos package it is being compiled against.
 var _ = new(http.Request)
 var _ = new(context.Context)
-var _ = binding.MapProto
+var _ = new(middleware.Middleware)
+var _ = new(transport.Transporter)
+var _ = binding.BindVars
 var _ = mux.NewRouter
 
 const _ = http1.SupportPackageIsVersion1
@@ -32,17 +36,226 @@ type BlogServiceHandler interface {
 }
 
 func NewBlogServiceHandler(srv BlogServiceHandler, opts ...http1.HandleOption) http.Handler {
+	h := http1.DefaultHandleOptions()
+	for _, o := range opts {
+		o(&h)
+	}
 	r := mux.NewRouter()
 
-	r.Handle("/v1/article/", http1.NewHandler(srv.CreateArticle, opts...)).Methods("POST")
+	r.HandleFunc("/v1/article/", func(w http.ResponseWriter, r *http.Request) {
+		var in CreateArticleRequest
+		if err := h.Decode(r, &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
 
-	r.Handle("/v1/article/{id}", http1.NewHandler(srv.UpdateArticle, opts...)).Methods("PUT")
+		next := func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.CreateArticle(ctx, req.(*CreateArticleRequest))
+		}
+		if h.Middleware != nil {
+			next = h.Middleware(next)
+		}
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/blog.api.v1.BlogService/CreateArticle")
+		out, err := next(ctx, &in)
+		if err != nil {
+			h.Error(w, r, err)
+			return
+		}
+		reply := out.(*CreateArticleReply)
+		if err := h.Encode(w, r, reply); err != nil {
+			h.Error(w, r, err)
+		}
+	}).Methods("POST")
 
-	r.Handle("/v1/article/{id}", http1.NewHandler(srv.DeleteArticle, opts...)).Methods("DELETE")
+	r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
+		var in UpdateArticleRequest
+		if err := h.Decode(r, &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
 
-	r.Handle("/v1/article/{id}", http1.NewHandler(srv.GetArticle, opts...)).Methods("GET")
+		if err := binding.BindVars(mux.Vars(r), &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
 
-	r.Handle("/v1/article/", http1.NewHandler(srv.ListArticle, opts...)).Methods("GET")
+		next := func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.UpdateArticle(ctx, req.(*UpdateArticleRequest))
+		}
+		if h.Middleware != nil {
+			next = h.Middleware(next)
+		}
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/blog.api.v1.BlogService/UpdateArticle")
+		out, err := next(ctx, &in)
+		if err != nil {
+			h.Error(w, r, err)
+			return
+		}
+		reply := out.(*UpdateArticleReply)
+		if err := h.Encode(w, r, reply); err != nil {
+			h.Error(w, r, err)
+		}
+	}).Methods("PUT")
+
+	r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
+		var in DeleteArticleRequest
+		if err := h.Decode(r, &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
+
+		if err := binding.BindVars(mux.Vars(r), &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
+
+		next := func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.DeleteArticle(ctx, req.(*DeleteArticleRequest))
+		}
+		if h.Middleware != nil {
+			next = h.Middleware(next)
+		}
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/blog.api.v1.BlogService/DeleteArticle")
+		out, err := next(ctx, &in)
+		if err != nil {
+			h.Error(w, r, err)
+			return
+		}
+		reply := out.(*DeleteArticleReply)
+		if err := h.Encode(w, r, reply); err != nil {
+			h.Error(w, r, err)
+		}
+	}).Methods("DELETE")
+
+	r.HandleFunc("/v1/article/{id}", func(w http.ResponseWriter, r *http.Request) {
+		var in GetArticleRequest
+		if err := h.Decode(r, &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
+
+		if err := binding.BindVars(mux.Vars(r), &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
+
+		next := func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.GetArticle(ctx, req.(*GetArticleRequest))
+		}
+		if h.Middleware != nil {
+			next = h.Middleware(next)
+		}
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/blog.api.v1.BlogService/GetArticle")
+		out, err := next(ctx, &in)
+		if err != nil {
+			h.Error(w, r, err)
+			return
+		}
+		reply := out.(*GetArticleReply)
+		if err := h.Encode(w, r, reply); err != nil {
+			h.Error(w, r, err)
+		}
+	}).Methods("GET")
+
+	r.HandleFunc("/v1/article/", func(w http.ResponseWriter, r *http.Request) {
+		var in ListArticleRequest
+		if err := h.Decode(r, &in); err != nil {
+			h.Error(w, r, err)
+			return
+		}
+
+		next := func(ctx context.Context, req interface{}) (interface{}, error) {
+			return srv.ListArticle(ctx, req.(*ListArticleRequest))
+		}
+		if h.Middleware != nil {
+			next = h.Middleware(next)
+		}
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/blog.api.v1.BlogService/ListArticle")
+		out, err := next(ctx, &in)
+		if err != nil {
+			h.Error(w, r, err)
+			return
+		}
+		reply := out.(*ListArticleReply)
+		if err := h.Encode(w, r, reply); err != nil {
+			h.Error(w, r, err)
+		}
+	}).Methods("GET")
 
 	return r
 }
+
+type BlogServiceHTTPClient interface {
+	CreateArticle(ctx context.Context, req *CreateArticleRequest, opts ...http1.CallOption) (rsp *CreateArticleReply, err error)
+
+	DeleteArticle(ctx context.Context, req *DeleteArticleRequest, opts ...http1.CallOption) (rsp *DeleteArticleReply, err error)
+
+	GetArticle(ctx context.Context, req *GetArticleRequest, opts ...http1.CallOption) (rsp *GetArticleReply, err error)
+
+	ListArticle(ctx context.Context, req *ListArticleRequest, opts ...http1.CallOption) (rsp *ListArticleReply, err error)
+
+	UpdateArticle(ctx context.Context, req *UpdateArticleRequest, opts ...http1.CallOption) (rsp *UpdateArticleReply, err error)
+}
+
+type BlogServiceHTTPClientImpl struct {
+	cc *http1.Client
+}
+
+func NewBlogServiceHTTPClient(client *http1.Client) BlogServiceHTTPClient {
+	return &BlogServiceHTTPClientImpl{client}
+}
+
+func (c *BlogServiceHTTPClientImpl) CreateArticle(ctx context.Context, in *CreateArticleRequest, opts ...http1.CallOption) (*CreateArticleReply, error) {
+	var out CreateArticleReply
+	path := binding.EncodePath("POST", "/v1/article/", in)
+	opts = append(opts, http1.Method("/blog.api.v1.BlogService/CreateArticle"))
+
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
+
+	return &out, err
+}
+
+func (c *BlogServiceHTTPClientImpl) DeleteArticle(ctx context.Context, in *DeleteArticleRequest, opts ...http1.CallOption) (*DeleteArticleReply, error) {
+	var out DeleteArticleReply
+	path := binding.EncodePath("DELETE", "/v1/article/{id}", in)
+	opts = append(opts, http1.Method("/blog.api.v1.BlogService/DeleteArticle"))
+
+	err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...)
+
+	return &out, err
+}
+
+func (c *BlogServiceHTTPClientImpl) GetArticle(ctx context.Context, in *GetArticleRequest, opts ...http1.CallOption) (*GetArticleReply, error) {
+	var out GetArticleReply
+	path := binding.EncodePath("GET", "/v1/article/{id}", in)
+	opts = append(opts, http1.Method("/blog.api.v1.BlogService/GetArticle"))
+
+	err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
+
+	return &out, err
+}
+
+func (c *BlogServiceHTTPClientImpl) ListArticle(ctx context.Context, in *ListArticleRequest, opts ...http1.CallOption) (*ListArticleReply, error) {
+	var out ListArticleReply
+	path := binding.EncodePath("GET", "/v1/article/", in)
+	opts = append(opts, http1.Method("/blog.api.v1.BlogService/ListArticle"))
+
+	err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
+
+	return &out, err
+}
+
+func (c *BlogServiceHTTPClientImpl) UpdateArticle(ctx context.Context, in *UpdateArticleRequest, opts ...http1.CallOption) (*UpdateArticleReply, error) {
+	var out UpdateArticleReply
+	path := binding.EncodePath("PUT", "/v1/article/{id}", in)
+	opts = append(opts, http1.Method("/blog.api.v1.BlogService/UpdateArticle"))
+
+	err := c.cc.Invoke(ctx, "PUT", path, in, &out, opts...)
+
+	return &out, err
+}
diff --git a/examples/blog/api/blog/v1/error_reason.pb.go b/examples/blog/api/blog/v1/error_reason.pb.go
index d91e26bf..708113e7 100644
--- a/examples/blog/api/blog/v1/error_reason.pb.go
+++ b/examples/blog/api/blog/v1/error_reason.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
-// source: api/blog/v1/error_reason.proto
+// 	protoc        v3.15.7
+// source: blog/api/blog/v1/error_reason.proto
 
 package v1
 
@@ -50,11 +50,11 @@ func (x ErrorReason) String() string {
 }
 
 func (ErrorReason) Descriptor() protoreflect.EnumDescriptor {
-	return file_api_blog_v1_error_reason_proto_enumTypes[0].Descriptor()
+	return file_blog_api_blog_v1_error_reason_proto_enumTypes[0].Descriptor()
 }
 
 func (ErrorReason) Type() protoreflect.EnumType {
-	return &file_api_blog_v1_error_reason_proto_enumTypes[0]
+	return &file_blog_api_blog_v1_error_reason_proto_enumTypes[0]
 }
 
 func (x ErrorReason) Number() protoreflect.EnumNumber {
@@ -63,44 +63,44 @@ func (x ErrorReason) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use ErrorReason.Descriptor instead.
 func (ErrorReason) EnumDescriptor() ([]byte, []int) {
-	return file_api_blog_v1_error_reason_proto_rawDescGZIP(), []int{0}
+	return file_blog_api_blog_v1_error_reason_proto_rawDescGZIP(), []int{0}
 }
 
-var File_api_blog_v1_error_reason_proto protoreflect.FileDescriptor
-
-var file_api_blog_v1_error_reason_proto_rawDesc = []byte{
-	0x0a, 0x1e, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x72,
-	0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2a, 0x34, 0x0a,
-	0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d,
-	0x54, 0x49, 0x54, 0x4c, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12,
-	0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e,
-	0x47, 0x10, 0x01, 0x42, 0x57, 0x0a, 0x0e, 0x62, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x65,
-	0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
-	0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72,
-	0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x62, 0x6c,
-	0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0xa2, 0x02, 0x0d, 0x41,
-	0x50, 0x49, 0x42, 0x6c, 0x6f, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x33,
+var File_blog_api_blog_v1_error_reason_proto protoreflect.FileDescriptor
+
+var file_blog_api_blog_v1_error_reason_proto_rawDesc = []byte{
+	0x0a, 0x23, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f,
+	0x76, 0x31, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x62, 0x6c, 0x6f, 0x67, 0x2e,
+	0x76, 0x31, 0x2a, 0x34, 0x0a, 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f,
+	0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x49, 0x54, 0x4c, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49,
+	0x4e, 0x47, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, 0x4d,
+	0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x42, 0x57, 0x0a, 0x0e, 0x62, 0x6c, 0x6f, 0x67,
+	0x2e, 0x76, 0x31, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x69,
+	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74,
+	0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+	0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x3b, 0x76,
+	0x31, 0xa2, 0x02, 0x0d, 0x41, 0x50, 0x49, 0x42, 0x6c, 0x6f, 0x67, 0x45, 0x72, 0x72, 0x6f, 0x72,
+	0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_api_blog_v1_error_reason_proto_rawDescOnce sync.Once
-	file_api_blog_v1_error_reason_proto_rawDescData = file_api_blog_v1_error_reason_proto_rawDesc
+	file_blog_api_blog_v1_error_reason_proto_rawDescOnce sync.Once
+	file_blog_api_blog_v1_error_reason_proto_rawDescData = file_blog_api_blog_v1_error_reason_proto_rawDesc
 )
 
-func file_api_blog_v1_error_reason_proto_rawDescGZIP() []byte {
-	file_api_blog_v1_error_reason_proto_rawDescOnce.Do(func() {
-		file_api_blog_v1_error_reason_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_blog_v1_error_reason_proto_rawDescData)
+func file_blog_api_blog_v1_error_reason_proto_rawDescGZIP() []byte {
+	file_blog_api_blog_v1_error_reason_proto_rawDescOnce.Do(func() {
+		file_blog_api_blog_v1_error_reason_proto_rawDescData = protoimpl.X.CompressGZIP(file_blog_api_blog_v1_error_reason_proto_rawDescData)
 	})
-	return file_api_blog_v1_error_reason_proto_rawDescData
+	return file_blog_api_blog_v1_error_reason_proto_rawDescData
 }
 
-var file_api_blog_v1_error_reason_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_api_blog_v1_error_reason_proto_goTypes = []interface{}{
+var file_blog_api_blog_v1_error_reason_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_blog_api_blog_v1_error_reason_proto_goTypes = []interface{}{
 	(ErrorReason)(0), // 0: api.blog.v1.ErrorReason
 }
-var file_api_blog_v1_error_reason_proto_depIdxs = []int32{
+var file_blog_api_blog_v1_error_reason_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for method output_type
 	0, // [0:0] is the sub-list for method input_type
 	0, // [0:0] is the sub-list for extension type_name
@@ -108,27 +108,27 @@ var file_api_blog_v1_error_reason_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for field type_name
 }
 
-func init() { file_api_blog_v1_error_reason_proto_init() }
-func file_api_blog_v1_error_reason_proto_init() {
-	if File_api_blog_v1_error_reason_proto != nil {
+func init() { file_blog_api_blog_v1_error_reason_proto_init() }
+func file_blog_api_blog_v1_error_reason_proto_init() {
+	if File_blog_api_blog_v1_error_reason_proto != nil {
 		return
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_api_blog_v1_error_reason_proto_rawDesc,
+			RawDescriptor: file_blog_api_blog_v1_error_reason_proto_rawDesc,
 			NumEnums:      1,
 			NumMessages:   0,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_api_blog_v1_error_reason_proto_goTypes,
-		DependencyIndexes: file_api_blog_v1_error_reason_proto_depIdxs,
-		EnumInfos:         file_api_blog_v1_error_reason_proto_enumTypes,
+		GoTypes:           file_blog_api_blog_v1_error_reason_proto_goTypes,
+		DependencyIndexes: file_blog_api_blog_v1_error_reason_proto_depIdxs,
+		EnumInfos:         file_blog_api_blog_v1_error_reason_proto_enumTypes,
 	}.Build()
-	File_api_blog_v1_error_reason_proto = out.File
-	file_api_blog_v1_error_reason_proto_rawDesc = nil
-	file_api_blog_v1_error_reason_proto_goTypes = nil
-	file_api_blog_v1_error_reason_proto_depIdxs = nil
+	File_blog_api_blog_v1_error_reason_proto = out.File
+	file_blog_api_blog_v1_error_reason_proto_rawDesc = nil
+	file_blog_api_blog_v1_error_reason_proto_goTypes = nil
+	file_blog_api_blog_v1_error_reason_proto_depIdxs = nil
 }
diff --git a/examples/blog/cmd/blog/wire_gen.go b/examples/blog/cmd/blog/wire_gen.go
index 5156de64..a5a1bb8e 100644
--- a/examples/blog/cmd/blog/wire_gen.go
+++ b/examples/blog/cmd/blog/wire_gen.go
@@ -19,7 +19,7 @@ import (
 // Injectors from wire.go:
 
 // initApp init kratos application.
-func initApp(confServer *conf.Server, confData *conf.Data, tracerProvider trace.TracerProvider, logger log.Logger) (*kratos.App, func(), error) {
+func initApp(confServer *conf.Server, confData *conf.Data, traceTracerProvider trace.TracerProvider, logger log.Logger) (*kratos.App, func(), error) {
 	dataData, cleanup, err := data.NewData(confData, logger)
 	if err != nil {
 		return nil, nil, err
@@ -27,8 +27,8 @@ func initApp(confServer *conf.Server, confData *conf.Data, tracerProvider trace.
 	articleRepo := data.NewArticleRepo(dataData, logger)
 	articleUsecase := biz.NewArticleUsecase(articleRepo, logger)
 	blogService := service.NewBlogService(articleUsecase, logger)
-	httpServer := server.NewHTTPServer(confServer, tracerProvider, blogService)
-	grpcServer := server.NewGRPCServer(confServer, tracerProvider, blogService)
+	httpServer := server.NewHTTPServer(confServer, traceTracerProvider, blogService)
+	grpcServer := server.NewGRPCServer(confServer, traceTracerProvider, blogService)
 	app := newApp(logger, httpServer, grpcServer)
 	return app, func() {
 		cleanup()
diff --git a/examples/blog/internal/conf/conf.pb.go b/examples/blog/internal/conf/conf.pb.go
index 31489d8b..e84eb106 100644
--- a/examples/blog/internal/conf/conf.pb.go
+++ b/examples/blog/internal/conf/conf.pb.go
@@ -1,15 +1,15 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.6.1
-// source: internal/conf/conf.proto
+// 	protoc        v3.15.7
+// source: blog/internal/conf/conf.proto
 
 package conf
 
 import (
-	duration "github.com/golang/protobuf/ptypes/duration"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	durationpb "google.golang.org/protobuf/types/known/durationpb"
 	reflect "reflect"
 	sync "sync"
 )
@@ -34,7 +34,7 @@ type Bootstrap struct {
 func (x *Bootstrap) Reset() {
 	*x = Bootstrap{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[0]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -47,7 +47,7 @@ func (x *Bootstrap) String() string {
 func (*Bootstrap) ProtoMessage() {}
 
 func (x *Bootstrap) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[0]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -60,7 +60,7 @@ func (x *Bootstrap) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Bootstrap.ProtoReflect.Descriptor instead.
 func (*Bootstrap) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{0}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *Bootstrap) GetTrace() *Trace {
@@ -96,7 +96,7 @@ type Server struct {
 func (x *Server) Reset() {
 	*x = Server{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[1]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -109,7 +109,7 @@ func (x *Server) String() string {
 func (*Server) ProtoMessage() {}
 
 func (x *Server) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[1]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -122,7 +122,7 @@ func (x *Server) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Server.ProtoReflect.Descriptor instead.
 func (*Server) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{1}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *Server) GetHttp() *Server_HTTP {
@@ -151,7 +151,7 @@ type Data struct {
 func (x *Data) Reset() {
 	*x = Data{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[2]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -164,7 +164,7 @@ func (x *Data) String() string {
 func (*Data) ProtoMessage() {}
 
 func (x *Data) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[2]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -177,7 +177,7 @@ func (x *Data) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Data.ProtoReflect.Descriptor instead.
 func (*Data) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{2}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *Data) GetDatabase() *Data_Database {
@@ -205,7 +205,7 @@ type Trace struct {
 func (x *Trace) Reset() {
 	*x = Trace{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[3]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -218,7 +218,7 @@ func (x *Trace) String() string {
 func (*Trace) ProtoMessage() {}
 
 func (x *Trace) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[3]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -231,7 +231,7 @@ func (x *Trace) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Trace.ProtoReflect.Descriptor instead.
 func (*Trace) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{3}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *Trace) GetEndpoint() string {
@@ -246,15 +246,15 @@ type Server_HTTP struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Network string             `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
-	Addr    string             `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
-	Timeout *duration.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"`
+	Network string               `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
+	Addr    string               `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
+	Timeout *durationpb.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"`
 }
 
 func (x *Server_HTTP) Reset() {
 	*x = Server_HTTP{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[4]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -267,7 +267,7 @@ func (x *Server_HTTP) String() string {
 func (*Server_HTTP) ProtoMessage() {}
 
 func (x *Server_HTTP) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[4]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -280,7 +280,7 @@ func (x *Server_HTTP) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Server_HTTP.ProtoReflect.Descriptor instead.
 func (*Server_HTTP) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{1, 0}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{1, 0}
 }
 
 func (x *Server_HTTP) GetNetwork() string {
@@ -297,7 +297,7 @@ func (x *Server_HTTP) GetAddr() string {
 	return ""
 }
 
-func (x *Server_HTTP) GetTimeout() *duration.Duration {
+func (x *Server_HTTP) GetTimeout() *durationpb.Duration {
 	if x != nil {
 		return x.Timeout
 	}
@@ -309,15 +309,15 @@ type Server_GRPC struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Network string             `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
-	Addr    string             `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
-	Timeout *duration.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"`
+	Network string               `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
+	Addr    string               `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
+	Timeout *durationpb.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"`
 }
 
 func (x *Server_GRPC) Reset() {
 	*x = Server_GRPC{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[5]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -330,7 +330,7 @@ func (x *Server_GRPC) String() string {
 func (*Server_GRPC) ProtoMessage() {}
 
 func (x *Server_GRPC) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[5]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -343,7 +343,7 @@ func (x *Server_GRPC) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Server_GRPC.ProtoReflect.Descriptor instead.
 func (*Server_GRPC) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{1, 1}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{1, 1}
 }
 
 func (x *Server_GRPC) GetNetwork() string {
@@ -360,7 +360,7 @@ func (x *Server_GRPC) GetAddr() string {
 	return ""
 }
 
-func (x *Server_GRPC) GetTimeout() *duration.Duration {
+func (x *Server_GRPC) GetTimeout() *durationpb.Duration {
 	if x != nil {
 		return x.Timeout
 	}
@@ -379,7 +379,7 @@ type Data_Database struct {
 func (x *Data_Database) Reset() {
 	*x = Data_Database{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[6]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -392,7 +392,7 @@ func (x *Data_Database) String() string {
 func (*Data_Database) ProtoMessage() {}
 
 func (x *Data_Database) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[6]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -405,7 +405,7 @@ func (x *Data_Database) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Data_Database.ProtoReflect.Descriptor instead.
 func (*Data_Database) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{2, 0}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{2, 0}
 }
 
 func (x *Data_Database) GetDriver() string {
@@ -427,19 +427,19 @@ type Data_Redis struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Network      string             `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
-	Addr         string             `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
-	Password     string             `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
-	Db           int32              `protobuf:"varint,4,opt,name=db,proto3" json:"db,omitempty"`
-	DialTimeout  *duration.Duration `protobuf:"bytes,5,opt,name=dial_timeout,json=dialTimeout,proto3" json:"dial_timeout,omitempty"`
-	ReadTimeout  *duration.Duration `protobuf:"bytes,6,opt,name=read_timeout,json=readTimeout,proto3" json:"read_timeout,omitempty"`
-	WriteTimeout *duration.Duration `protobuf:"bytes,7,opt,name=write_timeout,json=writeTimeout,proto3" json:"write_timeout,omitempty"`
+	Network      string               `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
+	Addr         string               `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
+	Password     string               `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
+	Db           int32                `protobuf:"varint,4,opt,name=db,proto3" json:"db,omitempty"`
+	DialTimeout  *durationpb.Duration `protobuf:"bytes,5,opt,name=dial_timeout,json=dialTimeout,proto3" json:"dial_timeout,omitempty"`
+	ReadTimeout  *durationpb.Duration `protobuf:"bytes,6,opt,name=read_timeout,json=readTimeout,proto3" json:"read_timeout,omitempty"`
+	WriteTimeout *durationpb.Duration `protobuf:"bytes,7,opt,name=write_timeout,json=writeTimeout,proto3" json:"write_timeout,omitempty"`
 }
 
 func (x *Data_Redis) Reset() {
 	*x = Data_Redis{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_conf_conf_proto_msgTypes[7]
+		mi := &file_blog_internal_conf_conf_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -452,7 +452,7 @@ func (x *Data_Redis) String() string {
 func (*Data_Redis) ProtoMessage() {}
 
 func (x *Data_Redis) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_conf_conf_proto_msgTypes[7]
+	mi := &file_blog_internal_conf_conf_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -465,7 +465,7 @@ func (x *Data_Redis) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Data_Redis.ProtoReflect.Descriptor instead.
 func (*Data_Redis) Descriptor() ([]byte, []int) {
-	return file_internal_conf_conf_proto_rawDescGZIP(), []int{2, 1}
+	return file_blog_internal_conf_conf_proto_rawDescGZIP(), []int{2, 1}
 }
 
 func (x *Data_Redis) GetNetwork() string {
@@ -496,131 +496,131 @@ func (x *Data_Redis) GetDb() int32 {
 	return 0
 }
 
-func (x *Data_Redis) GetDialTimeout() *duration.Duration {
+func (x *Data_Redis) GetDialTimeout() *durationpb.Duration {
 	if x != nil {
 		return x.DialTimeout
 	}
 	return nil
 }
 
-func (x *Data_Redis) GetReadTimeout() *duration.Duration {
+func (x *Data_Redis) GetReadTimeout() *durationpb.Duration {
 	if x != nil {
 		return x.ReadTimeout
 	}
 	return nil
 }
 
-func (x *Data_Redis) GetWriteTimeout() *duration.Duration {
+func (x *Data_Redis) GetWriteTimeout() *durationpb.Duration {
 	if x != nil {
 		return x.WriteTimeout
 	}
 	return nil
 }
 
-var File_internal_conf_conf_proto protoreflect.FileDescriptor
-
-var file_internal_conf_conf_proto_rawDesc = []byte{
-	0x0a, 0x18, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x2f,
-	0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x6b, 0x72, 0x61, 0x74,
-	0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
-	0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
-	0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x22, 0xa4, 0x01, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, 0x31,
-	0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
-	0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
-	0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63,
-	0x65, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1c, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
-	0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52,
-	0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69,
-	0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x44, 0x61, 0x74,
-	0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xcc, 0x02, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x12, 0x35, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x21, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
-	0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48,
-	0x54, 0x54, 0x50, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x35, 0x0a, 0x04, 0x67, 0x72, 0x70,
-	0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73,
-	0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x53,
-	0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63,
-	0x1a, 0x69, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77,
+var File_blog_internal_conf_conf_proto protoreflect.FileDescriptor
+
+var file_blog_internal_conf_conf_proto_rawDesc = []byte{
+	0x0a, 0x1d, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
+	0x63, 0x6f, 0x6e, 0x66, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+	0x14, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
+	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x01, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74,
+	0x72, 0x61, 0x70, 0x12, 0x31, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65,
+	0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x52,
+	0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e,
+	0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04,
+	0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x72, 0x61,
+	0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e,
+	0x66, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xcc, 0x02, 0x0a,
+	0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69,
+	0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65, 0x72,
+	0x76, 0x65, 0x72, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x35,
+	0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6b,
+	0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63,
+	0x6f, 0x6e, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52,
+	0x04, 0x67, 0x72, 0x70, 0x63, 0x1a, 0x69, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x12, 0x18, 0x0a,
+	0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74,
+	0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44,
+	0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
+	0x1a, 0x69, 0x0a, 0x04, 0x47, 0x52, 0x50, 0x43, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77,
 	0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f,
 	0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
 	0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
 	0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
 	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x1a, 0x69, 0x0a, 0x04, 0x47,
-	0x52, 0x50, 0x43, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01,
+	0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xdb, 0x03, 0x0a, 0x04,
+	0x44, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e,
+	0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x44, 0x61,
+	0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x08, 0x64, 0x61, 0x74,
+	0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e,
+	0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x44, 0x61, 0x74, 0x61,
+	0x2e, 0x52, 0x65, 0x64, 0x69, 0x73, 0x52, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x1a, 0x3a, 0x0a,
+	0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69,
+	0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65,
+	0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x9d, 0x02, 0x0a, 0x05, 0x52, 0x65,
+	0x64, 0x69, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01,
 	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a,
 	0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64,
-	0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74,
-	0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xdb, 0x03, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12,
-	0x3f, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x23, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
-	0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61,
-	0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65,
-	0x12, 0x36, 0x0a, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x20, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
-	0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x64, 0x69,
-	0x73, 0x52, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x1a, 0x3a, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61,
-	0x62, 0x61, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06,
-	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f,
-	0x75, 0x72, 0x63, 0x65, 0x1a, 0x9d, 0x02, 0x0a, 0x05, 0x52, 0x65, 0x64, 0x69, 0x73, 0x12, 0x18,
-	0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08,
-	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
-	0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x62, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x62, 0x12, 0x3c, 0x0a, 0x0c, 0x64, 0x69, 0x61, 0x6c,
-	0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
-	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x54,
-	0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x74,
-	0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67,
-	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44,
-	0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x54, 0x69, 0x6d,
-	0x65, 0x6f, 0x75, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x74, 0x69,
-	0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f,
-	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75,
-	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x69, 0x6d,
-	0x65, 0x6f, 0x75, 0x74, 0x22, 0x23, 0x0a, 0x05, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a,
-	0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74,
-	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f,
-	0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
-	0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
-	0x63, 0x6f, 0x6e, 0x66, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x33,
+	0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x0e, 0x0a,
+	0x02, 0x64, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64, 0x62, 0x12, 0x3c, 0x0a,
+	0x0c, 0x64, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b,
+	0x64, 0x69, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x72,
+	0x65, 0x61, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65,
+	0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x77, 0x72, 0x69,
+	0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x77, 0x72, 0x69,
+	0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x23, 0x0a, 0x05, 0x54, 0x72, 0x61,
+	0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x3e,
+	0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d,
+	0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78,
+	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x69, 0x6e, 0x74, 0x65,
+	0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_internal_conf_conf_proto_rawDescOnce sync.Once
-	file_internal_conf_conf_proto_rawDescData = file_internal_conf_conf_proto_rawDesc
+	file_blog_internal_conf_conf_proto_rawDescOnce sync.Once
+	file_blog_internal_conf_conf_proto_rawDescData = file_blog_internal_conf_conf_proto_rawDesc
 )
 
-func file_internal_conf_conf_proto_rawDescGZIP() []byte {
-	file_internal_conf_conf_proto_rawDescOnce.Do(func() {
-		file_internal_conf_conf_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_conf_conf_proto_rawDescData)
+func file_blog_internal_conf_conf_proto_rawDescGZIP() []byte {
+	file_blog_internal_conf_conf_proto_rawDescOnce.Do(func() {
+		file_blog_internal_conf_conf_proto_rawDescData = protoimpl.X.CompressGZIP(file_blog_internal_conf_conf_proto_rawDescData)
 	})
-	return file_internal_conf_conf_proto_rawDescData
-}
-
-var file_internal_conf_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
-var file_internal_conf_conf_proto_goTypes = []interface{}{
-	(*Bootstrap)(nil),         // 0: kratos.internal.conf.Bootstrap
-	(*Server)(nil),            // 1: kratos.internal.conf.Server
-	(*Data)(nil),              // 2: kratos.internal.conf.Data
-	(*Trace)(nil),             // 3: kratos.internal.conf.Trace
-	(*Server_HTTP)(nil),       // 4: kratos.internal.conf.Server.HTTP
-	(*Server_GRPC)(nil),       // 5: kratos.internal.conf.Server.GRPC
-	(*Data_Database)(nil),     // 6: kratos.internal.conf.Data.Database
-	(*Data_Redis)(nil),        // 7: kratos.internal.conf.Data.Redis
-	(*duration.Duration)(nil), // 8: google.protobuf.Duration
-}
-var file_internal_conf_conf_proto_depIdxs = []int32{
+	return file_blog_internal_conf_conf_proto_rawDescData
+}
+
+var file_blog_internal_conf_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
+var file_blog_internal_conf_conf_proto_goTypes = []interface{}{
+	(*Bootstrap)(nil),           // 0: kratos.internal.conf.Bootstrap
+	(*Server)(nil),              // 1: kratos.internal.conf.Server
+	(*Data)(nil),                // 2: kratos.internal.conf.Data
+	(*Trace)(nil),               // 3: kratos.internal.conf.Trace
+	(*Server_HTTP)(nil),         // 4: kratos.internal.conf.Server.HTTP
+	(*Server_GRPC)(nil),         // 5: kratos.internal.conf.Server.GRPC
+	(*Data_Database)(nil),       // 6: kratos.internal.conf.Data.Database
+	(*Data_Redis)(nil),          // 7: kratos.internal.conf.Data.Redis
+	(*durationpb.Duration)(nil), // 8: google.protobuf.Duration
+}
+var file_blog_internal_conf_conf_proto_depIdxs = []int32{
 	3,  // 0: kratos.internal.conf.Bootstrap.trace:type_name -> kratos.internal.conf.Trace
 	1,  // 1: kratos.internal.conf.Bootstrap.server:type_name -> kratos.internal.conf.Server
 	2,  // 2: kratos.internal.conf.Bootstrap.data:type_name -> kratos.internal.conf.Data
@@ -640,13 +640,13 @@ var file_internal_conf_conf_proto_depIdxs = []int32{
 	0,  // [0:12] is the sub-list for field type_name
 }
 
-func init() { file_internal_conf_conf_proto_init() }
-func file_internal_conf_conf_proto_init() {
-	if File_internal_conf_conf_proto != nil {
+func init() { file_blog_internal_conf_conf_proto_init() }
+func file_blog_internal_conf_conf_proto_init() {
+	if File_blog_internal_conf_conf_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_internal_conf_conf_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Bootstrap); i {
 			case 0:
 				return &v.state
@@ -658,7 +658,7 @@ func file_internal_conf_conf_proto_init() {
 				return nil
 			}
 		}
-		file_internal_conf_conf_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Server); i {
 			case 0:
 				return &v.state
@@ -670,7 +670,7 @@ func file_internal_conf_conf_proto_init() {
 				return nil
 			}
 		}
-		file_internal_conf_conf_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Data); i {
 			case 0:
 				return &v.state
@@ -682,7 +682,7 @@ func file_internal_conf_conf_proto_init() {
 				return nil
 			}
 		}
-		file_internal_conf_conf_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Trace); i {
 			case 0:
 				return &v.state
@@ -694,7 +694,7 @@ func file_internal_conf_conf_proto_init() {
 				return nil
 			}
 		}
-		file_internal_conf_conf_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Server_HTTP); i {
 			case 0:
 				return &v.state
@@ -706,7 +706,7 @@ func file_internal_conf_conf_proto_init() {
 				return nil
 			}
 		}
-		file_internal_conf_conf_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Server_GRPC); i {
 			case 0:
 				return &v.state
@@ -718,7 +718,7 @@ func file_internal_conf_conf_proto_init() {
 				return nil
 			}
 		}
-		file_internal_conf_conf_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Data_Database); i {
 			case 0:
 				return &v.state
@@ -730,7 +730,7 @@ func file_internal_conf_conf_proto_init() {
 				return nil
 			}
 		}
-		file_internal_conf_conf_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+		file_blog_internal_conf_conf_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Data_Redis); i {
 			case 0:
 				return &v.state
@@ -747,18 +747,18 @@ func file_internal_conf_conf_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_internal_conf_conf_proto_rawDesc,
+			RawDescriptor: file_blog_internal_conf_conf_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   8,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
-		GoTypes:           file_internal_conf_conf_proto_goTypes,
-		DependencyIndexes: file_internal_conf_conf_proto_depIdxs,
-		MessageInfos:      file_internal_conf_conf_proto_msgTypes,
+		GoTypes:           file_blog_internal_conf_conf_proto_goTypes,
+		DependencyIndexes: file_blog_internal_conf_conf_proto_depIdxs,
+		MessageInfos:      file_blog_internal_conf_conf_proto_msgTypes,
 	}.Build()
-	File_internal_conf_conf_proto = out.File
-	file_internal_conf_conf_proto_rawDesc = nil
-	file_internal_conf_conf_proto_goTypes = nil
-	file_internal_conf_conf_proto_depIdxs = nil
+	File_blog_internal_conf_conf_proto = out.File
+	file_blog_internal_conf_conf_proto_rawDesc = nil
+	file_blog_internal_conf_conf_proto_goTypes = nil
+	file_blog_internal_conf_conf_proto_depIdxs = nil
 }
diff --git a/examples/go.sum b/examples/go.sum
index db897a57..7e76597c 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -195,6 +195,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
 github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
@@ -677,6 +678,7 @@ golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roY
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/examples/helloworld/helloworld/helloworld.pb.go b/examples/helloworld/helloworld/helloworld.pb.go
index 96274168..d3161911 100644
--- a/examples/helloworld/helloworld/helloworld.pb.go
+++ b/examples/helloworld/helloworld/helloworld.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
-// source: helloworld/helloworld.proto
+// 	protoc        v3.15.7
+// source: helloworld/helloworld/helloworld.proto
 
 package helloworld
 
@@ -33,7 +33,7 @@ type HelloRequest struct {
 func (x *HelloRequest) Reset() {
 	*x = HelloRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_helloworld_helloworld_proto_msgTypes[0]
+		mi := &file_helloworld_helloworld_helloworld_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -46,7 +46,7 @@ func (x *HelloRequest) String() string {
 func (*HelloRequest) ProtoMessage() {}
 
 func (x *HelloRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_helloworld_helloworld_proto_msgTypes[0]
+	mi := &file_helloworld_helloworld_helloworld_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -59,7 +59,7 @@ func (x *HelloRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
 func (*HelloRequest) Descriptor() ([]byte, []int) {
-	return file_helloworld_helloworld_proto_rawDescGZIP(), []int{0}
+	return file_helloworld_helloworld_helloworld_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *HelloRequest) GetName() string {
@@ -81,7 +81,7 @@ type HelloReply struct {
 func (x *HelloReply) Reset() {
 	*x = HelloReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_helloworld_helloworld_proto_msgTypes[1]
+		mi := &file_helloworld_helloworld_helloworld_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -94,7 +94,7 @@ func (x *HelloReply) String() string {
 func (*HelloReply) ProtoMessage() {}
 
 func (x *HelloReply) ProtoReflect() protoreflect.Message {
-	mi := &file_helloworld_helloworld_proto_msgTypes[1]
+	mi := &file_helloworld_helloworld_helloworld_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -107,7 +107,7 @@ func (x *HelloReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.
 func (*HelloReply) Descriptor() ([]byte, []int) {
-	return file_helloworld_helloworld_proto_rawDescGZIP(), []int{1}
+	return file_helloworld_helloworld_helloworld_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *HelloReply) GetMessage() string {
@@ -117,49 +117,50 @@ func (x *HelloReply) GetMessage() string {
 	return ""
 }
 
-var File_helloworld_helloworld_proto protoreflect.FileDescriptor
-
-var file_helloworld_helloworld_proto_rawDesc = []byte{
-	0x0a, 0x1b, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65, 0x6c,
-	0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x68,
-	0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
-	0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x48,
-	0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x32, 0x63, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65, 0x72, 0x12, 0x58,
-	0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x18, 0x2e, 0x68, 0x65, 0x6c,
-	0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c,
-	0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1a, 0x82, 0xd3,
-	0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c,
-	0x64, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68,
-	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73,
-	0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
-	0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
-	0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+var File_helloworld_helloworld_helloworld_proto protoreflect.FileDescriptor
+
+var file_helloworld_helloworld_helloworld_proto_rawDesc = []byte{
+	0x0a, 0x26, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65, 0x6c,
+	0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72,
+	0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77,
+	0x6f, 0x72, 0x6c, 0x64, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69,
+	0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52,
+	0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x63,
+	0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x08, 0x53, 0x61, 0x79,
+	0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x18, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72,
+	0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x16, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c,
+	0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12,
+	0x12, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x7b, 0x6e, 0x61,
+	0x6d, 0x65, 0x7d, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+	0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74,
+	0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
+	0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c,
+	0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_helloworld_helloworld_proto_rawDescOnce sync.Once
-	file_helloworld_helloworld_proto_rawDescData = file_helloworld_helloworld_proto_rawDesc
+	file_helloworld_helloworld_helloworld_proto_rawDescOnce sync.Once
+	file_helloworld_helloworld_helloworld_proto_rawDescData = file_helloworld_helloworld_helloworld_proto_rawDesc
 )
 
-func file_helloworld_helloworld_proto_rawDescGZIP() []byte {
-	file_helloworld_helloworld_proto_rawDescOnce.Do(func() {
-		file_helloworld_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_helloworld_proto_rawDescData)
+func file_helloworld_helloworld_helloworld_proto_rawDescGZIP() []byte {
+	file_helloworld_helloworld_helloworld_proto_rawDescOnce.Do(func() {
+		file_helloworld_helloworld_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_helloworld_helloworld_proto_rawDescData)
 	})
-	return file_helloworld_helloworld_proto_rawDescData
+	return file_helloworld_helloworld_helloworld_proto_rawDescData
 }
 
-var file_helloworld_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_helloworld_helloworld_proto_goTypes = []interface{}{
+var file_helloworld_helloworld_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_helloworld_helloworld_helloworld_proto_goTypes = []interface{}{
 	(*HelloRequest)(nil), // 0: helloworld.HelloRequest
 	(*HelloReply)(nil),   // 1: helloworld.HelloReply
 }
-var file_helloworld_helloworld_proto_depIdxs = []int32{
+var file_helloworld_helloworld_helloworld_proto_depIdxs = []int32{
 	0, // 0: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest
 	1, // 1: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply
 	1, // [1:2] is the sub-list for method output_type
@@ -169,13 +170,13 @@ var file_helloworld_helloworld_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for field type_name
 }
 
-func init() { file_helloworld_helloworld_proto_init() }
-func file_helloworld_helloworld_proto_init() {
-	if File_helloworld_helloworld_proto != nil {
+func init() { file_helloworld_helloworld_helloworld_proto_init() }
+func file_helloworld_helloworld_helloworld_proto_init() {
+	if File_helloworld_helloworld_helloworld_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_helloworld_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+		file_helloworld_helloworld_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*HelloRequest); i {
 			case 0:
 				return &v.state
@@ -187,7 +188,7 @@ func file_helloworld_helloworld_proto_init() {
 				return nil
 			}
 		}
-		file_helloworld_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+		file_helloworld_helloworld_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*HelloReply); i {
 			case 0:
 				return &v.state
@@ -204,18 +205,18 @@ func file_helloworld_helloworld_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_helloworld_helloworld_proto_rawDesc,
+			RawDescriptor: file_helloworld_helloworld_helloworld_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   2,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
-		GoTypes:           file_helloworld_helloworld_proto_goTypes,
-		DependencyIndexes: file_helloworld_helloworld_proto_depIdxs,
-		MessageInfos:      file_helloworld_helloworld_proto_msgTypes,
+		GoTypes:           file_helloworld_helloworld_helloworld_proto_goTypes,
+		DependencyIndexes: file_helloworld_helloworld_helloworld_proto_depIdxs,
+		MessageInfos:      file_helloworld_helloworld_helloworld_proto_msgTypes,
 	}.Build()
-	File_helloworld_helloworld_proto = out.File
-	file_helloworld_helloworld_proto_rawDesc = nil
-	file_helloworld_helloworld_proto_goTypes = nil
-	file_helloworld_helloworld_proto_depIdxs = nil
+	File_helloworld_helloworld_helloworld_proto = out.File
+	file_helloworld_helloworld_helloworld_proto_rawDesc = nil
+	file_helloworld_helloworld_helloworld_proto_goTypes = nil
+	file_helloworld_helloworld_helloworld_proto_depIdxs = nil
 }
diff --git a/examples/helloworld/helloworld/helloworld_grpc.pb.go b/examples/helloworld/helloworld/helloworld_grpc.pb.go
index 4e1c32b3..26ea9ebe 100644
--- a/examples/helloworld/helloworld/helloworld_grpc.pb.go
+++ b/examples/helloworld/helloworld/helloworld_grpc.pb.go
@@ -99,5 +99,5 @@ var Greeter_ServiceDesc = grpc.ServiceDesc{
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "helloworld/helloworld.proto",
+	Metadata: "helloworld/helloworld/helloworld.proto",
 }
diff --git a/examples/helloworld/helloworld/helloworld_http.pb.go b/examples/helloworld/helloworld/helloworld_http.pb.go
index 9e895cf1..f358a62a 100644
--- a/examples/helloworld/helloworld/helloworld_http.pb.go
+++ b/examples/helloworld/helloworld/helloworld_http.pb.go
@@ -4,6 +4,8 @@ package helloworld
 
 import (
 	context "context"
+	middleware "github.com/go-kratos/kratos/v2/middleware"
+	transport "github.com/go-kratos/kratos/v2/transport"
 	http1 "github.com/go-kratos/kratos/v2/transport/http"
 	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
 	mux "github.com/gorilla/mux"
@@ -14,7 +16,9 @@ import (
 // is compatible with the kratos package it is being compiled against.
 var _ = new(http.Request)
 var _ = new(context.Context)
-var _ = binding.MapProto
+var _ = new(middleware.Middleware)
+var _ = new(transport.Transporter)
+var _ = binding.BindVars
 var _ = mux.NewRouter
 
 const _ = http1.SupportPackageIsVersion1
@@ -48,7 +52,9 @@ func NewGreeterHandler(srv GreeterHandler, opts ...http1.HandleOption) http.Hand
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/helloworld.Greeter/SayHello")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -74,14 +80,12 @@ func NewGreeterHTTPClient(client *http1.Client) GreeterHTTPClient {
 	return &GreeterHTTPClientImpl{client}
 }
 
-func (c *GreeterHTTPClientImpl) SayHello(ctx context.Context, in *HelloRequest, opts ...http1.CallOption) (out *HelloReply, err error) {
+func (c *GreeterHTTPClientImpl) SayHello(ctx context.Context, in *HelloRequest, opts ...http1.CallOption) (*HelloReply, error) {
+	var out HelloReply
 	path := binding.EncodePath("GET", "/helloworld/{name}", in)
-	out = &HelloReply{}
+	opts = append(opts, http1.Method("/helloworld.Greeter/SayHello"))
 
-	err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("GET"), http1.PathPattern("/helloworld/{name}"))
+	err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
diff --git a/examples/metadata/client/main.go b/examples/metadata/client/main.go
new file mode 100644
index 00000000..dabc9180
--- /dev/null
+++ b/examples/metadata/client/main.go
@@ -0,0 +1,65 @@
+package main
+
+import (
+	"context"
+	"fmt"
+
+	pb "github.com/go-kratos/kratos/examples/helloworld/helloworld"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/metadata"
+	"github.com/go-kratos/kratos/v2/middleware"
+	"github.com/go-kratos/kratos/v2/middleware/recovery"
+	transgrpc "github.com/go-kratos/kratos/v2/transport/grpc"
+	"github.com/go-kratos/kratos/v2/transport/http"
+	transhttp "github.com/go-kratos/kratos/v2/transport/http"
+	grpcmd "google.golang.org/grpc/metadata"
+)
+
+func main() {
+	callHTTP()
+	callGRPC()
+}
+
+func callHTTP() {
+	logger := log.DefaultLogger
+	conn, err := transhttp.NewClient(
+		context.Background(),
+		transhttp.WithMiddleware(
+			recovery.Recovery(),
+		),
+		transhttp.WithEndpoint("127.0.0.1:8000"),
+	)
+	if err != nil {
+		panic(err)
+	}
+	client := pb.NewGreeterHTTPClient(conn)
+	md := metadata.New(map[string][]string{"kratos-extra": {"2233"}})
+	reply, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: "kratos"}, http.Metadata(md))
+	if err != nil {
+		panic(err)
+	}
+	logger.Log(log.LevelInfo, "msg", fmt.Sprintf("[http] SayHello %s\n", reply.Message))
+}
+
+func callGRPC() {
+	logger := log.DefaultLogger
+	conn, err := transgrpc.DialInsecure(
+		context.Background(),
+		transgrpc.WithEndpoint("127.0.0.1:9000"),
+		transgrpc.WithMiddleware(
+			middleware.Chain(
+				recovery.Recovery(),
+			),
+		),
+	)
+	if err != nil {
+		panic(err)
+	}
+	client := pb.NewGreeterClient(conn)
+	ctx := grpcmd.AppendToOutgoingContext(context.Background(), "kratos-extra", "2233")
+	reply, err := client.SayHello(ctx, &pb.HelloRequest{Name: "kratos"})
+	if err != nil {
+		panic(err)
+	}
+	logger.Log(log.LevelInfo, "msg", fmt.Sprintf("[grpc] SayHello %+v", reply))
+}
diff --git a/examples/metadata/server/main.go b/examples/metadata/server/main.go
new file mode 100644
index 00000000..c5601b55
--- /dev/null
+++ b/examples/metadata/server/main.go
@@ -0,0 +1,73 @@
+package main
+
+import (
+	"context"
+	"fmt"
+	"os"
+
+	pb "github.com/go-kratos/kratos/examples/helloworld/helloworld"
+	"github.com/go-kratos/kratos/v2"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/middleware/logging"
+	"github.com/go-kratos/kratos/v2/middleware/recovery"
+	"github.com/go-kratos/kratos/v2/transport"
+	"github.com/go-kratos/kratos/v2/transport/grpc"
+	"github.com/go-kratos/kratos/v2/transport/http"
+)
+
+// go build -ldflags "-X main.Version=x.y.z"
+var (
+	// Name is the name of the compiled software.
+	Name = "helloworld"
+	// Version is the version of the compiled software.
+	Version = "v1.0.0"
+)
+
+// server is used to implement helloworld.GreeterServer.
+type server struct {
+	pb.UnimplementedGreeterServer
+}
+
+// SayHello implements helloworld.GreeterServer
+func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
+	var extra string
+	if tr, ok := transport.FromServerContext(ctx); ok {
+		extra = tr.Metadata().Get("kratos-extra")
+	}
+	return &pb.HelloReply{Message: fmt.Sprintf("Hello %s and %s", in.Name, extra)}, nil
+}
+
+func main() {
+	logger := log.NewStdLogger(os.Stdout)
+	log := log.NewHelper(logger)
+
+	grpcSrv := grpc.NewServer(
+		grpc.Address(":9000"),
+		grpc.Middleware(
+			recovery.Recovery(),
+			logging.Server(logger),
+		))
+
+	s := &server{}
+	pb.RegisterGreeterServer(grpcSrv, s)
+
+	httpSrv := http.NewServer(http.Address(":8000"))
+	httpSrv.HandlePrefix("/", pb.NewGreeterHandler(s,
+		http.Middleware(
+			recovery.Recovery(),
+			logging.Server(logger),
+		)),
+	)
+
+	app := kratos.New(
+		kratos.Name(Name),
+		kratos.Server(
+			httpSrv,
+			grpcSrv,
+		),
+	)
+
+	if err := app.Run(); err != nil {
+		log.Error(err)
+	}
+}
diff --git a/examples/proto/echo_service.pb.go b/examples/proto/echo_service.pb.go
index c8e37f9c..669731b2 100644
--- a/examples/proto/echo_service.pb.go
+++ b/examples/proto/echo_service.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
-// source: echo_service.proto
+// 	protoc        v3.15.7
+// source: proto/echo_service.proto
 
 package testproto
 
@@ -68,11 +68,11 @@ func (x Corpus) String() string {
 }
 
 func (Corpus) Descriptor() protoreflect.EnumDescriptor {
-	return file_echo_service_proto_enumTypes[0].Descriptor()
+	return file_proto_echo_service_proto_enumTypes[0].Descriptor()
 }
 
 func (Corpus) Type() protoreflect.EnumType {
-	return &file_echo_service_proto_enumTypes[0]
+	return &file_proto_echo_service_proto_enumTypes[0]
 }
 
 func (x Corpus) Number() protoreflect.EnumNumber {
@@ -81,7 +81,7 @@ func (x Corpus) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use Corpus.Descriptor instead.
 func (Corpus) EnumDescriptor() ([]byte, []int) {
-	return file_echo_service_proto_rawDescGZIP(), []int{0}
+	return file_proto_echo_service_proto_rawDescGZIP(), []int{0}
 }
 
 // Embedded represents a message embedded in SimpleMessage.
@@ -99,7 +99,7 @@ type Embedded struct {
 func (x *Embedded) Reset() {
 	*x = Embedded{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_echo_service_proto_msgTypes[0]
+		mi := &file_proto_echo_service_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -112,7 +112,7 @@ func (x *Embedded) String() string {
 func (*Embedded) ProtoMessage() {}
 
 func (x *Embedded) ProtoReflect() protoreflect.Message {
-	mi := &file_echo_service_proto_msgTypes[0]
+	mi := &file_proto_echo_service_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -125,7 +125,7 @@ func (x *Embedded) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Embedded.ProtoReflect.Descriptor instead.
 func (*Embedded) Descriptor() ([]byte, []int) {
-	return file_echo_service_proto_rawDescGZIP(), []int{0}
+	return file_proto_echo_service_proto_rawDescGZIP(), []int{0}
 }
 
 func (m *Embedded) GetMark() isEmbedded_Mark {
@@ -189,7 +189,7 @@ type SimpleMessage struct {
 func (x *SimpleMessage) Reset() {
 	*x = SimpleMessage{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_echo_service_proto_msgTypes[1]
+		mi := &file_proto_echo_service_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -202,7 +202,7 @@ func (x *SimpleMessage) String() string {
 func (*SimpleMessage) ProtoMessage() {}
 
 func (x *SimpleMessage) ProtoReflect() protoreflect.Message {
-	mi := &file_echo_service_proto_msgTypes[1]
+	mi := &file_proto_echo_service_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -215,7 +215,7 @@ func (x *SimpleMessage) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use SimpleMessage.ProtoReflect.Descriptor instead.
 func (*SimpleMessage) Descriptor() ([]byte, []int) {
-	return file_echo_service_proto_rawDescGZIP(), []int{1}
+	return file_proto_echo_service_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *SimpleMessage) GetId() string {
@@ -334,7 +334,7 @@ type DynamicMessage struct {
 func (x *DynamicMessage) Reset() {
 	*x = DynamicMessage{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_echo_service_proto_msgTypes[2]
+		mi := &file_proto_echo_service_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -347,7 +347,7 @@ func (x *DynamicMessage) String() string {
 func (*DynamicMessage) ProtoMessage() {}
 
 func (x *DynamicMessage) ProtoReflect() protoreflect.Message {
-	mi := &file_echo_service_proto_msgTypes[2]
+	mi := &file_proto_echo_service_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -360,7 +360,7 @@ func (x *DynamicMessage) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DynamicMessage.ProtoReflect.Descriptor instead.
 func (*DynamicMessage) Descriptor() ([]byte, []int) {
-	return file_echo_service_proto_rawDescGZIP(), []int{2}
+	return file_proto_echo_service_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *DynamicMessage) GetStructField() *structpb.Struct {
@@ -389,7 +389,7 @@ type DynamicMessageUpdate struct {
 func (x *DynamicMessageUpdate) Reset() {
 	*x = DynamicMessageUpdate{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_echo_service_proto_msgTypes[3]
+		mi := &file_proto_echo_service_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -402,7 +402,7 @@ func (x *DynamicMessageUpdate) String() string {
 func (*DynamicMessageUpdate) ProtoMessage() {}
 
 func (x *DynamicMessageUpdate) ProtoReflect() protoreflect.Message {
-	mi := &file_echo_service_proto_msgTypes[3]
+	mi := &file_proto_echo_service_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -415,7 +415,7 @@ func (x *DynamicMessageUpdate) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DynamicMessageUpdate.ProtoReflect.Descriptor instead.
 func (*DynamicMessageUpdate) Descriptor() ([]byte, []int) {
-	return file_echo_service_proto_rawDescGZIP(), []int{3}
+	return file_proto_echo_service_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *DynamicMessageUpdate) GetBody() *DynamicMessage {
@@ -432,129 +432,129 @@ func (x *DynamicMessageUpdate) GetUpdateMask() *fieldmaskpb.FieldMask {
 	return nil
 }
 
-var File_echo_service_proto protoreflect.FileDescriptor
-
-var file_echo_service_proto_rawDesc = []byte{
-	0x0a, 0x12, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
-	0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
-	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67,
-	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66,
-	0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
-	0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a,
-	0x08, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x70, 0x72, 0x6f,
-	0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x70,
-	0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x42, 0x06, 0x0a,
-	0x04, 0x6d, 0x61, 0x72, 0x6b, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65,
-	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x69, 0x6e,
-	0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x6c,
-	0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x14, 0x0a, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x06,
-	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74,
-	0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65,
-	0x64, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x02, 0x65, 0x6e, 0x18,
-	0x06, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x02, 0x65, 0x6e, 0x12, 0x25, 0x0a, 0x02, 0x6e,
-	0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x48, 0x01, 0x52, 0x02,
-	0x6e, 0x6f, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01,
-	0x28, 0x0e, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43,
-	0x6f, 0x72, 0x70, 0x75, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x42, 0x06, 0x0a,
-	0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x65, 0x78, 0x74, 0x22, 0x85, 0x01, 0x0a,
-	0x0e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
-	0x3a, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b,
-	0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x37, 0x0a, 0x0b, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46,
-	0x69, 0x65, 0x6c, 0x64, 0x22, 0x82, 0x01, 0x0a, 0x14, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63,
-	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a,
-	0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65,
-	0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x3b, 0x0a, 0x0b,
-	0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75,
-	0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x2a, 0x5a, 0x0a, 0x06, 0x43, 0x6f, 0x72,
-	0x70, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x49, 0x56, 0x45, 0x52, 0x53, 0x41, 0x4c,
-	0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x57, 0x45, 0x42, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x49,
-	0x4d, 0x41, 0x47, 0x45, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c,
-	0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x45, 0x57, 0x53, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08,
-	0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x53, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49,
-	0x44, 0x45, 0x4f, 0x10, 0x06, 0x32, 0xcf, 0x05, 0x0a, 0x0b, 0x45, 0x63, 0x68, 0x6f, 0x53, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xf2, 0x01, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x18,
-	0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c,
-	0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x22, 0xb5, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0xae, 0x01, 0x22, 0x15, 0x2f, 0x76,
-	0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b,
-	0x69, 0x64, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70,
-	0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75,
-	0x6d, 0x7d, 0x5a, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
-	0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d,
-	0x7d, 0x2f, 0x7b, 0x6c, 0x61, 0x6e, 0x67, 0x7d, 0x5a, 0x31, 0x12, 0x2f, 0x2f, 0x76, 0x31, 0x2f,
-	0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x31, 0x2f, 0x7b, 0x69,
-	0x64, 0x7d, 0x2f, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x73,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f,
-	0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x32,
-	0x2f, 0x7b, 0x6e, 0x6f, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x7d, 0x12, 0x60, 0x0a, 0x08, 0x45, 0x63,
-	0x68, 0x6f, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d,
-	0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93,
-	0x02, 0x1a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
-	0x65, 0x63, 0x68, 0x6f, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x85, 0x01, 0x0a,
-	0x10, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64,
-	0x79, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79,
-	0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44,
+var File_proto_echo_service_proto protoreflect.FileDescriptor
+
+var file_proto_echo_service_proto_rawDesc = []byte{
+	0x0a, 0x18, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x65, 0x73, 0x74,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70,
+	0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a, 0x08, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12,
+	0x1c, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x48, 0x00, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a,
+	0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e,
+	0x6f, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6d, 0x61, 0x72, 0x6b, 0x22, 0x84, 0x02, 0x0a, 0x0d,
+	0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a,
+	0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a,
+	0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12,
+	0x1b, 0x0a, 0x08, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x03, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x14, 0x0a, 0x04,
+	0x6c, 0x61, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6c, 0x61,
+	0x6e, 0x67, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45,
+	0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
+	0x10, 0x0a, 0x02, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x02, 0x65,
+	0x6e, 0x12, 0x25, 0x0a, 0x02, 0x6e, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
+	0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64,
+	0x65, 0x64, 0x48, 0x01, 0x52, 0x02, 0x6e, 0x6f, 0x12, 0x29, 0x0a, 0x06, 0x63, 0x6f, 0x72, 0x70,
+	0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x72,
+	0x70, 0x75, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x65,
+	0x78, 0x74, 0x22, 0x85, 0x01, 0x0a, 0x0e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f,
+	0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
+	0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c,
+	0x64, 0x12, 0x37, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x82, 0x01, 0x0a, 0x14, 0x44,
 	0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64,
-	0x61, 0x74, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31,
-	0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x72, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x62, 0x04,
-	0x62, 0x6f, 0x64, 0x79, 0x12, 0x6c, 0x0a, 0x0a, 0x45, 0x63, 0x68, 0x6f, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53,
-	0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74,
+	0x61, 0x74, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x19, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79,
+	0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x62, 0x6f,
+	0x64, 0x79, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73,
+	0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d,
+	0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x2a,
+	0x5a, 0x0a, 0x06, 0x43, 0x6f, 0x72, 0x70, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x49,
+	0x56, 0x45, 0x52, 0x53, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x57, 0x45, 0x42, 0x10,
+	0x01, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a,
+	0x05, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x45, 0x57, 0x53,
+	0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x53, 0x10, 0x05,
+	0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x10, 0x06, 0x32, 0xcf, 0x05, 0x0a, 0x0b,
+	0x45, 0x63, 0x68, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xf2, 0x01, 0x0a, 0x04,
+	0x45, 0x63, 0x68, 0x6f, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18,
+	0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c,
+	0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb5, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0xae, 0x01, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
+	0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31,
+	0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69,
+	0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x5a, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x2f,
+	0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x7b, 0x69, 0x64,
+	0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x6c, 0x61, 0x6e, 0x67, 0x7d, 0x5a, 0x31,
+	0x12, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63,
+	0x68, 0x6f, 0x31, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e,
+	0x75, 0x6d, 0x7d, 0x2f, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x6e, 0x6f, 0x74, 0x65,
+	0x7d, 0x5a, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+	0x2f, 0x65, 0x63, 0x68, 0x6f, 0x32, 0x2f, 0x7b, 0x6e, 0x6f, 0x2e, 0x6e, 0x6f, 0x74, 0x65, 0x7d,
+	0x12, 0x60, 0x0a, 0x08, 0x45, 0x63, 0x68, 0x6f, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x2e, 0x74,
 	0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22,
-	0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f,
-	0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75,
-	0x6d, 0x7d, 0x12, 0x73, 0x0a, 0x09, 0x45, 0x63, 0x68, 0x6f, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12,
-	0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61,
-	0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e,
-	0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x65,
-	0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x63,
-	0x68, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75,
-	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f,
-	0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e,
-	0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78,
+	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x3a,
+	0x01, 0x2a, 0x12, 0x85, 0x01, 0x0a, 0x10, 0x45, 0x63, 0x68, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x29, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65,
+	0x63, 0x68, 0x6f, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64,
+	0x79, 0x3a, 0x01, 0x2a, 0x62, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x6c, 0x0a, 0x0a, 0x45, 0x63,
+	0x68, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x1a, 0x18, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53,
+	0x69, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2a, 0x82, 0xd3,
+	0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
+	0x65, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x7b, 0x69,
+	0x64, 0x7d, 0x2f, 0x7b, 0x6e, 0x75, 0x6d, 0x7d, 0x12, 0x73, 0x0a, 0x09, 0x45, 0x63, 0x68, 0x6f,
+	0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32,
+	0x16, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x65, 0x63, 0x68,
+	0x6f, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x51, 0x5a,
+	0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b,
+	0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64,
+	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68,
+	0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73,
+	0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_echo_service_proto_rawDescOnce sync.Once
-	file_echo_service_proto_rawDescData = file_echo_service_proto_rawDesc
+	file_proto_echo_service_proto_rawDescOnce sync.Once
+	file_proto_echo_service_proto_rawDescData = file_proto_echo_service_proto_rawDesc
 )
 
-func file_echo_service_proto_rawDescGZIP() []byte {
-	file_echo_service_proto_rawDescOnce.Do(func() {
-		file_echo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_echo_service_proto_rawDescData)
+func file_proto_echo_service_proto_rawDescGZIP() []byte {
+	file_proto_echo_service_proto_rawDescOnce.Do(func() {
+		file_proto_echo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_echo_service_proto_rawDescData)
 	})
-	return file_echo_service_proto_rawDescData
+	return file_proto_echo_service_proto_rawDescData
 }
 
-var file_echo_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_echo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_echo_service_proto_goTypes = []interface{}{
+var file_proto_echo_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_proto_echo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_proto_echo_service_proto_goTypes = []interface{}{
 	(Corpus)(0),                   // 0: testproto.Corpus
 	(*Embedded)(nil),              // 1: testproto.Embedded
 	(*SimpleMessage)(nil),         // 2: testproto.SimpleMessage
@@ -564,7 +564,7 @@ var file_echo_service_proto_goTypes = []interface{}{
 	(*structpb.Value)(nil),        // 6: google.protobuf.Value
 	(*fieldmaskpb.FieldMask)(nil), // 7: google.protobuf.FieldMask
 }
-var file_echo_service_proto_depIdxs = []int32{
+var file_proto_echo_service_proto_depIdxs = []int32{
 	1,  // 0: testproto.SimpleMessage.status:type_name -> testproto.Embedded
 	1,  // 1: testproto.SimpleMessage.no:type_name -> testproto.Embedded
 	0,  // 2: testproto.SimpleMessage.corpus:type_name -> testproto.Corpus
@@ -589,13 +589,13 @@ var file_echo_service_proto_depIdxs = []int32{
 	0,  // [0:7] is the sub-list for field type_name
 }
 
-func init() { file_echo_service_proto_init() }
-func file_echo_service_proto_init() {
-	if File_echo_service_proto != nil {
+func init() { file_proto_echo_service_proto_init() }
+func file_proto_echo_service_proto_init() {
+	if File_proto_echo_service_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_echo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+		file_proto_echo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Embedded); i {
 			case 0:
 				return &v.state
@@ -607,7 +607,7 @@ func file_echo_service_proto_init() {
 				return nil
 			}
 		}
-		file_echo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+		file_proto_echo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*SimpleMessage); i {
 			case 0:
 				return &v.state
@@ -619,7 +619,7 @@ func file_echo_service_proto_init() {
 				return nil
 			}
 		}
-		file_echo_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+		file_proto_echo_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DynamicMessage); i {
 			case 0:
 				return &v.state
@@ -631,7 +631,7 @@ func file_echo_service_proto_init() {
 				return nil
 			}
 		}
-		file_echo_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+		file_proto_echo_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DynamicMessageUpdate); i {
 			case 0:
 				return &v.state
@@ -644,11 +644,11 @@ func file_echo_service_proto_init() {
 			}
 		}
 	}
-	file_echo_service_proto_msgTypes[0].OneofWrappers = []interface{}{
+	file_proto_echo_service_proto_msgTypes[0].OneofWrappers = []interface{}{
 		(*Embedded_Progress)(nil),
 		(*Embedded_Note)(nil),
 	}
-	file_echo_service_proto_msgTypes[1].OneofWrappers = []interface{}{
+	file_proto_echo_service_proto_msgTypes[1].OneofWrappers = []interface{}{
 		(*SimpleMessage_LineNum)(nil),
 		(*SimpleMessage_Lang)(nil),
 		(*SimpleMessage_En)(nil),
@@ -658,19 +658,19 @@ func file_echo_service_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_echo_service_proto_rawDesc,
+			RawDescriptor: file_proto_echo_service_proto_rawDesc,
 			NumEnums:      1,
 			NumMessages:   4,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
-		GoTypes:           file_echo_service_proto_goTypes,
-		DependencyIndexes: file_echo_service_proto_depIdxs,
-		EnumInfos:         file_echo_service_proto_enumTypes,
-		MessageInfos:      file_echo_service_proto_msgTypes,
+		GoTypes:           file_proto_echo_service_proto_goTypes,
+		DependencyIndexes: file_proto_echo_service_proto_depIdxs,
+		EnumInfos:         file_proto_echo_service_proto_enumTypes,
+		MessageInfos:      file_proto_echo_service_proto_msgTypes,
 	}.Build()
-	File_echo_service_proto = out.File
-	file_echo_service_proto_rawDesc = nil
-	file_echo_service_proto_goTypes = nil
-	file_echo_service_proto_depIdxs = nil
+	File_proto_echo_service_proto = out.File
+	file_proto_echo_service_proto_rawDesc = nil
+	file_proto_echo_service_proto_goTypes = nil
+	file_proto_echo_service_proto_depIdxs = nil
 }
diff --git a/examples/proto/echo_service_grpc.pb.go b/examples/proto/echo_service_grpc.pb.go
index 23374bdc..6174691b 100644
--- a/examples/proto/echo_service_grpc.pb.go
+++ b/examples/proto/echo_service_grpc.pb.go
@@ -257,5 +257,5 @@ var EchoService_ServiceDesc = grpc.ServiceDesc{
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "echo_service.proto",
+	Metadata: "proto/echo_service.proto",
 }
diff --git a/examples/proto/echo_service_http.pb.go b/examples/proto/echo_service_http.pb.go
index f9259558..ea1dfec0 100644
--- a/examples/proto/echo_service_http.pb.go
+++ b/examples/proto/echo_service_http.pb.go
@@ -4,6 +4,8 @@ package testproto
 
 import (
 	context "context"
+	middleware "github.com/go-kratos/kratos/v2/middleware"
+	transport "github.com/go-kratos/kratos/v2/transport"
 	http1 "github.com/go-kratos/kratos/v2/transport/http"
 	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
 	mux "github.com/gorilla/mux"
@@ -14,7 +16,9 @@ import (
 // is compatible with the kratos package it is being compiled against.
 var _ = new(http.Request)
 var _ = new(context.Context)
-var _ = binding.MapProto
+var _ = new(middleware.Middleware)
+var _ = new(transport.Transporter)
+var _ = binding.BindVars
 var _ = mux.NewRouter
 
 const _ = http1.SupportPackageIsVersion1
@@ -56,7 +60,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/Echo")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -85,7 +91,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/Echo")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -114,7 +122,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/Echo")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -143,7 +153,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/Echo")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -172,7 +184,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/Echo")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -196,7 +210,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/EchoBody")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -220,7 +236,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/EchoResponseBody")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -249,7 +267,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/EchoDelete")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -273,7 +293,9 @@ func NewEchoServiceHandler(srv EchoServiceHandler, opts ...http1.HandleOption) h
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/testproto.EchoService/EchoPatch")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -307,62 +329,52 @@ func NewEchoServiceHTTPClient(client *http1.Client) EchoServiceHTTPClient {
 	return &EchoServiceHTTPClientImpl{client}
 }
 
-func (c *EchoServiceHTTPClientImpl) Echo(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (out *SimpleMessage, err error) {
+func (c *EchoServiceHTTPClientImpl) Echo(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (*SimpleMessage, error) {
+	var out SimpleMessage
 	path := binding.EncodePath("POST", "/v1/example/echo/{id}", in)
-	out = &SimpleMessage{}
+	opts = append(opts, http1.Method("/testproto.EchoService/Echo"))
 
-	err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("POST"), http1.PathPattern("/v1/example/echo/{id}"))
+	err := c.cc.Invoke(ctx, "POST", path, nil, &out, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
 
-func (c *EchoServiceHTTPClientImpl) EchoBody(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (out *SimpleMessage, err error) {
+func (c *EchoServiceHTTPClientImpl) EchoBody(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (*SimpleMessage, error) {
+	var out SimpleMessage
 	path := binding.EncodePath("POST", "/v1/example/echo_body", in)
-	out = &SimpleMessage{}
+	opts = append(opts, http1.Method("/testproto.EchoService/EchoBody"))
 
-	err = c.cc.Invoke(ctx, path, in, &out, http1.Method("POST"), http1.PathPattern("/v1/example/echo_body"))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
 
-func (c *EchoServiceHTTPClientImpl) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (out *SimpleMessage, err error) {
+func (c *EchoServiceHTTPClientImpl) EchoDelete(ctx context.Context, in *SimpleMessage, opts ...http1.CallOption) (*SimpleMessage, error) {
+	var out SimpleMessage
 	path := binding.EncodePath("DELETE", "/v1/example/echo_delete/{id}/{num}", in)
-	out = &SimpleMessage{}
+	opts = append(opts, http1.Method("/testproto.EchoService/EchoDelete"))
 
-	err = c.cc.Invoke(ctx, path, nil, &out, http1.Method("DELETE"), http1.PathPattern("/v1/example/echo_delete/{id}/{num}"))
+	err := c.cc.Invoke(ctx, "DELETE", path, nil, &out, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
 
-func (c *EchoServiceHTTPClientImpl) EchoPatch(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (out *DynamicMessageUpdate, err error) {
+func (c *EchoServiceHTTPClientImpl) EchoPatch(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (*DynamicMessageUpdate, error) {
+	var out DynamicMessageUpdate
 	path := binding.EncodePath("PATCH", "/v1/example/echo_patch", in)
-	out = &DynamicMessageUpdate{}
+	opts = append(opts, http1.Method("/testproto.EchoService/EchoPatch"))
 
-	err = c.cc.Invoke(ctx, path, in.Body, &out, http1.Method("PATCH"), http1.PathPattern("/v1/example/echo_patch"))
+	err := c.cc.Invoke(ctx, "PATCH", path, in.Body, &out, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
 
-func (c *EchoServiceHTTPClientImpl) EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (out *DynamicMessageUpdate, err error) {
+func (c *EchoServiceHTTPClientImpl) EchoResponseBody(ctx context.Context, in *DynamicMessageUpdate, opts ...http1.CallOption) (*DynamicMessageUpdate, error) {
+	var out DynamicMessageUpdate
 	path := binding.EncodePath("POST", "/v1/example/echo_response_body", in)
-	out = &DynamicMessageUpdate{}
+	opts = append(opts, http1.Method("/testproto.EchoService/EchoResponseBody"))
 
-	err = c.cc.Invoke(ctx, path, in, &out.Body, http1.Method("POST"), http1.PathPattern("/v1/example/echo_response_body"))
+	err := c.cc.Invoke(ctx, "POST", path, in, &out.Body, opts...)
 
-	if err != nil {
-		return
-	}
-	return
+	return &out, err
 }
diff --git a/examples/proto/stream.pb.go b/examples/proto/stream.pb.go
index 04d55590..658d821e 100644
--- a/examples/proto/stream.pb.go
+++ b/examples/proto/stream.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
-// source: stream.proto
+// 	protoc        v3.15.7
+// source: proto/stream.proto
 
 package testproto
 
@@ -22,36 +22,36 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
-var File_stream_proto protoreflect.FileDescriptor
+var File_proto_stream_proto protoreflect.FileDescriptor
 
-var file_stream_proto_rawDesc = []byte{
-	0x0a, 0x0c, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09,
-	0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
-	0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
-	0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32,
-	0x69, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x12, 0x58, 0x0a, 0x08, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x16, 0x2e, 0x67,
-	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
-	0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70,
-	0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93,
-	0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f,
-	0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x30, 0x01, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69,
-	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74,
-	0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70,
-	0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x33,
+var file_proto_stream_proto_rawDesc = []byte{
+	0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
+	0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f,
+	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x62, 0x6f,
+	0x64, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x69, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x08, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f,
+	0x61, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x42, 0x6f, 0x64, 0x79,
+	0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78,
+	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x30, 0x01,
+	0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67,
+	0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f,
+	0x63, 0x6d, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67,
+	0x6f, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
+	0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
-var file_stream_proto_goTypes = []interface{}{
+var file_proto_stream_proto_goTypes = []interface{}{
 	(*emptypb.Empty)(nil),     // 0: google.protobuf.Empty
 	(*httpbody.HttpBody)(nil), // 1: google.api.HttpBody
 }
-var file_stream_proto_depIdxs = []int32{
+var file_proto_stream_proto_depIdxs = []int32{
 	0, // 0: testproto.StreamService.Download:input_type -> google.protobuf.Empty
 	1, // 1: testproto.StreamService.Download:output_type -> google.api.HttpBody
 	1, // [1:2] is the sub-list for method output_type
@@ -61,26 +61,26 @@ var file_stream_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for field type_name
 }
 
-func init() { file_stream_proto_init() }
-func file_stream_proto_init() {
-	if File_stream_proto != nil {
+func init() { file_proto_stream_proto_init() }
+func file_proto_stream_proto_init() {
+	if File_proto_stream_proto != nil {
 		return
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_stream_proto_rawDesc,
+			RawDescriptor: file_proto_stream_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   0,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
-		GoTypes:           file_stream_proto_goTypes,
-		DependencyIndexes: file_stream_proto_depIdxs,
+		GoTypes:           file_proto_stream_proto_goTypes,
+		DependencyIndexes: file_proto_stream_proto_depIdxs,
 	}.Build()
-	File_stream_proto = out.File
-	file_stream_proto_rawDesc = nil
-	file_stream_proto_goTypes = nil
-	file_stream_proto_depIdxs = nil
+	File_proto_stream_proto = out.File
+	file_proto_stream_proto_rawDesc = nil
+	file_proto_stream_proto_goTypes = nil
+	file_proto_stream_proto_depIdxs = nil
 }
diff --git a/examples/proto/stream_grpc.pb.go b/examples/proto/stream_grpc.pb.go
index 9dfe96f8..5f36aacd 100644
--- a/examples/proto/stream_grpc.pb.go
+++ b/examples/proto/stream_grpc.pb.go
@@ -126,5 +126,5 @@ var StreamService_ServiceDesc = grpc.ServiceDesc{
 			ServerStreams: true,
 		},
 	},
-	Metadata: "stream.proto",
+	Metadata: "proto/stream.proto",
 }
diff --git a/examples/proto/stream_http.pb.go b/examples/proto/stream_http.pb.go
deleted file mode 100644
index 160b0407..00000000
--- a/examples/proto/stream_http.pb.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Code generated by protoc-gen-go-http. DO NOT EDIT.
-
-package testproto
-
-import (
-	context "context"
-	http1 "github.com/go-kratos/kratos/v2/transport/http"
-	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
-	mux "github.com/gorilla/mux"
-	http "net/http"
-)
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the kratos package it is being compiled against.
-var _ = new(http.Request)
-var _ = new(context.Context)
-var _ = binding.MapProto
-var _ = mux.NewRouter
-
-const _ = http1.SupportPackageIsVersion1
-
-type StreamServiceHandler interface {
-}
-
-func NewStreamServiceHandler(srv StreamServiceHandler, opts ...http1.HandleOption) http.Handler {
-	h := http1.DefaultHandleOptions()
-	for _, o := range opts {
-		o(&h)
-	}
-	r := mux.NewRouter()
-
-	return r
-}
-
-type StreamServiceHTTPClient interface {
-}
-
-type StreamServiceHTTPClientImpl struct {
-	cc *http1.Client
-}
-
-func NewStreamServiceHTTPClient(client *http1.Client) StreamServiceHTTPClient {
-	return &StreamServiceHTTPClientImpl{client}
-}
diff --git a/examples/traces/api/message/message.pb.go b/examples/traces/api/message/message.pb.go
index ac77ed1e..6a053d0d 100644
--- a/examples/traces/api/message/message.pb.go
+++ b/examples/traces/api/message/message.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
-// source: message/message.proto
+// 	protoc        v3.15.7
+// source: traces/api/message/message.proto
 
 package v1
 
@@ -33,7 +33,7 @@ type GetUserMessageRequest struct {
 func (x *GetUserMessageRequest) Reset() {
 	*x = GetUserMessageRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_message_message_proto_msgTypes[0]
+		mi := &file_traces_api_message_message_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -46,7 +46,7 @@ func (x *GetUserMessageRequest) String() string {
 func (*GetUserMessageRequest) ProtoMessage() {}
 
 func (x *GetUserMessageRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_message_message_proto_msgTypes[0]
+	mi := &file_traces_api_message_message_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -59,7 +59,7 @@ func (x *GetUserMessageRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetUserMessageRequest.ProtoReflect.Descriptor instead.
 func (*GetUserMessageRequest) Descriptor() ([]byte, []int) {
-	return file_message_message_proto_rawDescGZIP(), []int{0}
+	return file_traces_api_message_message_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *GetUserMessageRequest) GetId() int64 {
@@ -87,7 +87,7 @@ type GetUserMessageReply struct {
 func (x *GetUserMessageReply) Reset() {
 	*x = GetUserMessageReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_message_message_proto_msgTypes[1]
+		mi := &file_traces_api_message_message_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -100,7 +100,7 @@ func (x *GetUserMessageReply) String() string {
 func (*GetUserMessageReply) ProtoMessage() {}
 
 func (x *GetUserMessageReply) ProtoReflect() protoreflect.Message {
-	mi := &file_message_message_proto_msgTypes[1]
+	mi := &file_traces_api_message_message_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -113,7 +113,7 @@ func (x *GetUserMessageReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetUserMessageReply.ProtoReflect.Descriptor instead.
 func (*GetUserMessageReply) Descriptor() ([]byte, []int) {
-	return file_message_message_proto_rawDescGZIP(), []int{1}
+	return file_traces_api_message_message_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *GetUserMessageReply) GetMessages() []*Message {
@@ -134,7 +134,7 @@ type Message struct {
 func (x *Message) Reset() {
 	*x = Message{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_message_message_proto_msgTypes[2]
+		mi := &file_traces_api_message_message_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -147,7 +147,7 @@ func (x *Message) String() string {
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	mi := &file_message_message_proto_msgTypes[2]
+	mi := &file_traces_api_message_message_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -160,7 +160,7 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message.ProtoReflect.Descriptor instead.
 func (*Message) Descriptor() ([]byte, []int) {
-	return file_message_message_proto_rawDescGZIP(), []int{2}
+	return file_traces_api_message_message_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *Message) GetContent() string {
@@ -170,61 +170,62 @@ func (x *Message) GetContent() string {
 	return ""
 }
 
-var File_message_message_proto protoreflect.FileDescriptor
-
-var file_message_message_proto_rawDesc = []byte{
-	0x0a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
-	0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
-	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e,
-	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14,
-	0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63,
-	0x6f, 0x75, 0x6e, 0x74, 0x22, 0x4a, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, 0x08, 0x6d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e,
-	0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
-	0x22, 0x23, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
-	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x32, 0x99, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74,
-	0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x2e, 0x61, 0x70,
-	0x69, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
-	0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x23, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12,
-	0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x75, 0x73, 0x65,
-	0x72, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x3a, 0x01,
-	0x2a, 0x42, 0x51, 0x0a, 0x0e, 0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x2e, 0x76, 0x31, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74,
-	0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x63,
-	0x65, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x76,
-	0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+var File_traces_api_message_message_proto protoreflect.FileDescriptor
+
+var file_traces_api_message_message_proto_rawDesc = []byte{
+	0x0a, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x12, 0x0e, 0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
+	0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61,
+	0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x22, 0x3d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22,
+	0x4a, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x07, 0x4d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+	0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x32, 0x99, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x12, 0x86, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
+	0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70,
+	0x6c, 0x79, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x2f,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x7b, 0x69, 0x64,
+	0x7d, 0x2f, 0x7b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x3a, 0x01, 0x2a, 0x42, 0x51, 0x0a, 0x0e,
+	0x61, 0x70, 0x69, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x50, 0x01,
+	0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d,
+	0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78,
+	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x70,
+	0x69, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_message_message_proto_rawDescOnce sync.Once
-	file_message_message_proto_rawDescData = file_message_message_proto_rawDesc
+	file_traces_api_message_message_proto_rawDescOnce sync.Once
+	file_traces_api_message_message_proto_rawDescData = file_traces_api_message_message_proto_rawDesc
 )
 
-func file_message_message_proto_rawDescGZIP() []byte {
-	file_message_message_proto_rawDescOnce.Do(func() {
-		file_message_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_message_message_proto_rawDescData)
+func file_traces_api_message_message_proto_rawDescGZIP() []byte {
+	file_traces_api_message_message_proto_rawDescOnce.Do(func() {
+		file_traces_api_message_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_traces_api_message_message_proto_rawDescData)
 	})
-	return file_message_message_proto_rawDescData
+	return file_traces_api_message_message_proto_rawDescData
 }
 
-var file_message_message_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_message_message_proto_goTypes = []interface{}{
+var file_traces_api_message_message_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_traces_api_message_message_proto_goTypes = []interface{}{
 	(*GetUserMessageRequest)(nil), // 0: api.message.v1.GetUserMessageRequest
 	(*GetUserMessageReply)(nil),   // 1: api.message.v1.GetUserMessageReply
 	(*Message)(nil),               // 2: api.message.v1.Message
 }
-var file_message_message_proto_depIdxs = []int32{
+var file_traces_api_message_message_proto_depIdxs = []int32{
 	2, // 0: api.message.v1.GetUserMessageReply.messages:type_name -> api.message.v1.Message
 	0, // 1: api.message.v1.MessageService.GetUserMessage:input_type -> api.message.v1.GetUserMessageRequest
 	1, // 2: api.message.v1.MessageService.GetUserMessage:output_type -> api.message.v1.GetUserMessageReply
@@ -235,13 +236,13 @@ var file_message_message_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_message_message_proto_init() }
-func file_message_message_proto_init() {
-	if File_message_message_proto != nil {
+func init() { file_traces_api_message_message_proto_init() }
+func file_traces_api_message_message_proto_init() {
+	if File_traces_api_message_message_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_message_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+		file_traces_api_message_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetUserMessageRequest); i {
 			case 0:
 				return &v.state
@@ -253,7 +254,7 @@ func file_message_message_proto_init() {
 				return nil
 			}
 		}
-		file_message_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+		file_traces_api_message_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetUserMessageReply); i {
 			case 0:
 				return &v.state
@@ -265,7 +266,7 @@ func file_message_message_proto_init() {
 				return nil
 			}
 		}
-		file_message_message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+		file_traces_api_message_message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message); i {
 			case 0:
 				return &v.state
@@ -282,18 +283,18 @@ func file_message_message_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_message_message_proto_rawDesc,
+			RawDescriptor: file_traces_api_message_message_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   3,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
-		GoTypes:           file_message_message_proto_goTypes,
-		DependencyIndexes: file_message_message_proto_depIdxs,
-		MessageInfos:      file_message_message_proto_msgTypes,
+		GoTypes:           file_traces_api_message_message_proto_goTypes,
+		DependencyIndexes: file_traces_api_message_message_proto_depIdxs,
+		MessageInfos:      file_traces_api_message_message_proto_msgTypes,
 	}.Build()
-	File_message_message_proto = out.File
-	file_message_message_proto_rawDesc = nil
-	file_message_message_proto_goTypes = nil
-	file_message_message_proto_depIdxs = nil
+	File_traces_api_message_message_proto = out.File
+	file_traces_api_message_message_proto_rawDesc = nil
+	file_traces_api_message_message_proto_goTypes = nil
+	file_traces_api_message_message_proto_depIdxs = nil
 }
diff --git a/examples/traces/api/message/message_grpc.pb.go b/examples/traces/api/message/message_grpc.pb.go
index 161dde11..fb752503 100644
--- a/examples/traces/api/message/message_grpc.pb.go
+++ b/examples/traces/api/message/message_grpc.pb.go
@@ -97,5 +97,5 @@ var MessageService_ServiceDesc = grpc.ServiceDesc{
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "message/message.proto",
+	Metadata: "traces/api/message/message.proto",
 }
diff --git a/examples/traces/api/message/message_http.pb.go b/examples/traces/api/message/message_http.pb.go
index 1dcf6d01..affc5d46 100644
--- a/examples/traces/api/message/message_http.pb.go
+++ b/examples/traces/api/message/message_http.pb.go
@@ -4,6 +4,8 @@ package v1
 
 import (
 	context "context"
+	middleware "github.com/go-kratos/kratos/v2/middleware"
+	transport "github.com/go-kratos/kratos/v2/transport"
 	http1 "github.com/go-kratos/kratos/v2/transport/http"
 	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
 	mux "github.com/gorilla/mux"
@@ -14,7 +16,9 @@ import (
 // is compatible with the kratos package it is being compiled against.
 var _ = new(http.Request)
 var _ = new(context.Context)
-var _ = binding.MapProto
+var _ = new(middleware.Middleware)
+var _ = new(transport.Transporter)
+var _ = binding.BindVars
 var _ = mux.NewRouter
 
 const _ = http1.SupportPackageIsVersion1
@@ -37,7 +41,7 @@ func NewMessageServiceHandler(srv MessageServiceHandler, opts ...http1.HandleOpt
 			return
 		}
 
-		if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
+		if err := binding.BindVars(mux.Vars(r), &in); err != nil {
 			h.Error(w, r, err)
 			return
 		}
@@ -48,7 +52,9 @@ func NewMessageServiceHandler(srv MessageServiceHandler, opts ...http1.HandleOpt
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/api.message.v1.MessageService/GetUserMessage")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -61,3 +67,25 @@ func NewMessageServiceHandler(srv MessageServiceHandler, opts ...http1.HandleOpt
 
 	return r
 }
+
+type MessageServiceHTTPClient interface {
+	GetUserMessage(ctx context.Context, req *GetUserMessageRequest, opts ...http1.CallOption) (rsp *GetUserMessageReply, err error)
+}
+
+type MessageServiceHTTPClientImpl struct {
+	cc *http1.Client
+}
+
+func NewMessageServiceHTTPClient(client *http1.Client) MessageServiceHTTPClient {
+	return &MessageServiceHTTPClientImpl{client}
+}
+
+func (c *MessageServiceHTTPClientImpl) GetUserMessage(ctx context.Context, in *GetUserMessageRequest, opts ...http1.CallOption) (*GetUserMessageReply, error) {
+	var out GetUserMessageReply
+	path := binding.EncodePath("GET", "/v1/message/user/{id}/{count}", in)
+	opts = append(opts, http1.Method("/api.message.v1.MessageService/GetUserMessage"))
+
+	err := c.cc.Invoke(ctx, "GET", path, in, &out, opts...)
+
+	return &out, err
+}
diff --git a/examples/traces/api/user/user.pb.go b/examples/traces/api/user/user.pb.go
index 28e30c54..570bbe71 100644
--- a/examples/traces/api/user/user.pb.go
+++ b/examples/traces/api/user/user.pb.go
@@ -1,8 +1,8 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.26.0
-// 	protoc        v3.14.0
-// source: user/user.proto
+// 	protoc        v3.15.7
+// source: traces/api/user/user.proto
 
 package v1
 
@@ -32,7 +32,7 @@ type GetMyMessagesRequest struct {
 func (x *GetMyMessagesRequest) Reset() {
 	*x = GetMyMessagesRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_user_proto_msgTypes[0]
+		mi := &file_traces_api_user_user_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -45,7 +45,7 @@ func (x *GetMyMessagesRequest) String() string {
 func (*GetMyMessagesRequest) ProtoMessage() {}
 
 func (x *GetMyMessagesRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_user_proto_msgTypes[0]
+	mi := &file_traces_api_user_user_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -58,7 +58,7 @@ func (x *GetMyMessagesRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetMyMessagesRequest.ProtoReflect.Descriptor instead.
 func (*GetMyMessagesRequest) Descriptor() ([]byte, []int) {
-	return file_user_user_proto_rawDescGZIP(), []int{0}
+	return file_traces_api_user_user_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *GetMyMessagesRequest) GetCount() int64 {
@@ -79,7 +79,7 @@ type GetMyMessagesReply struct {
 func (x *GetMyMessagesReply) Reset() {
 	*x = GetMyMessagesReply{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_user_proto_msgTypes[1]
+		mi := &file_traces_api_user_user_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -92,7 +92,7 @@ func (x *GetMyMessagesReply) String() string {
 func (*GetMyMessagesReply) ProtoMessage() {}
 
 func (x *GetMyMessagesReply) ProtoReflect() protoreflect.Message {
-	mi := &file_user_user_proto_msgTypes[1]
+	mi := &file_traces_api_user_user_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -105,7 +105,7 @@ func (x *GetMyMessagesReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetMyMessagesReply.ProtoReflect.Descriptor instead.
 func (*GetMyMessagesReply) Descriptor() ([]byte, []int) {
-	return file_user_user_proto_rawDescGZIP(), []int{1}
+	return file_traces_api_user_user_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *GetMyMessagesReply) GetMessages() []*Message {
@@ -126,7 +126,7 @@ type Message struct {
 func (x *Message) Reset() {
 	*x = Message{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_user_proto_msgTypes[2]
+		mi := &file_traces_api_user_user_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -139,7 +139,7 @@ func (x *Message) String() string {
 func (*Message) ProtoMessage() {}
 
 func (x *Message) ProtoReflect() protoreflect.Message {
-	mi := &file_user_user_proto_msgTypes[2]
+	mi := &file_traces_api_user_user_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -152,7 +152,7 @@ func (x *Message) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Message.ProtoReflect.Descriptor instead.
 func (*Message) Descriptor() ([]byte, []int) {
-	return file_user_user_proto_rawDescGZIP(), []int{2}
+	return file_traces_api_user_user_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *Message) GetContent() string {
@@ -162,58 +162,59 @@ func (x *Message) GetContent() string {
 	return ""
 }
 
-var File_user_user_proto protoreflect.FileDescriptor
-
-var file_user_user_proto_rawDesc = []byte{
-	0x0a, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x12, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x1c,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2c, 0x0a, 0x14,
-	0x47, 0x65, 0x74, 0x4d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x46, 0x0a, 0x12, 0x47, 0x65,
+var File_traces_api_user_user_proto protoreflect.FileDescriptor
+
+var file_traces_api_user_user_proto_rawDesc = []byte{
+	0x0a, 0x1a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x73, 0x65,
+	0x72, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x61, 0x70,
+	0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2c, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4d, 0x79,
+	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x46, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x4d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x30, 0x0a, 0x08, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x23, 0x0a,
+	0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x32, 0x84, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x7c, 0x0a, 0x0d, 0x47,
+	0x65, 0x74, 0x4d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x79,
+	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
 	0x74, 0x4d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
-	0x12, 0x30, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
-	0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x73, 0x22, 0x23, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a,
-	0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x32, 0x84, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72,
-	0x12, 0x7c, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
-	0x47, 0x65, 0x74, 0x4d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
-	0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
-	0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1c, 0x2f,
-	0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x2f, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x2f, 0x7b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x3a, 0x01, 0x2a, 0x42, 0x55,
-	0x0a, 0x0b, 0x61, 0x70, 0x69, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x50, 0x01, 0x5a,
-	0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b,
-	0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61,
-	0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2d, 0x68, 0x74, 0x74,
-	0x70, 0x2d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f,
-	0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73,
+	0x65, 0x72, 0x2f, 0x67, 0x65, 0x74, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x7b,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x7d, 0x3a, 0x01, 0x2a, 0x42, 0x55, 0x0a, 0x0b, 0x61, 0x70, 0x69,
+	0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73,
+	0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
+	0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x2d, 0x67, 0x72, 0x70,
+	0x63, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
-	file_user_user_proto_rawDescOnce sync.Once
-	file_user_user_proto_rawDescData = file_user_user_proto_rawDesc
+	file_traces_api_user_user_proto_rawDescOnce sync.Once
+	file_traces_api_user_user_proto_rawDescData = file_traces_api_user_user_proto_rawDesc
 )
 
-func file_user_user_proto_rawDescGZIP() []byte {
-	file_user_user_proto_rawDescOnce.Do(func() {
-		file_user_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_user_proto_rawDescData)
+func file_traces_api_user_user_proto_rawDescGZIP() []byte {
+	file_traces_api_user_user_proto_rawDescOnce.Do(func() {
+		file_traces_api_user_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_traces_api_user_user_proto_rawDescData)
 	})
-	return file_user_user_proto_rawDescData
+	return file_traces_api_user_user_proto_rawDescData
 }
 
-var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_user_user_proto_goTypes = []interface{}{
+var file_traces_api_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_traces_api_user_user_proto_goTypes = []interface{}{
 	(*GetMyMessagesRequest)(nil), // 0: api.user.v1.GetMyMessagesRequest
 	(*GetMyMessagesReply)(nil),   // 1: api.user.v1.GetMyMessagesReply
 	(*Message)(nil),              // 2: api.user.v1.Message
 }
-var file_user_user_proto_depIdxs = []int32{
+var file_traces_api_user_user_proto_depIdxs = []int32{
 	2, // 0: api.user.v1.GetMyMessagesReply.messages:type_name -> api.user.v1.Message
 	0, // 1: api.user.v1.User.GetMyMessages:input_type -> api.user.v1.GetMyMessagesRequest
 	1, // 2: api.user.v1.User.GetMyMessages:output_type -> api.user.v1.GetMyMessagesReply
@@ -224,13 +225,13 @@ var file_user_user_proto_depIdxs = []int32{
 	0, // [0:1] is the sub-list for field type_name
 }
 
-func init() { file_user_user_proto_init() }
-func file_user_user_proto_init() {
-	if File_user_user_proto != nil {
+func init() { file_traces_api_user_user_proto_init() }
+func file_traces_api_user_user_proto_init() {
+	if File_traces_api_user_user_proto != nil {
 		return
 	}
 	if !protoimpl.UnsafeEnabled {
-		file_user_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+		file_traces_api_user_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetMyMessagesRequest); i {
 			case 0:
 				return &v.state
@@ -242,7 +243,7 @@ func file_user_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+		file_traces_api_user_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*GetMyMessagesReply); i {
 			case 0:
 				return &v.state
@@ -254,7 +255,7 @@ func file_user_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+		file_traces_api_user_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Message); i {
 			case 0:
 				return &v.state
@@ -271,18 +272,18 @@ func file_user_user_proto_init() {
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_user_user_proto_rawDesc,
+			RawDescriptor: file_traces_api_user_user_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   3,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
-		GoTypes:           file_user_user_proto_goTypes,
-		DependencyIndexes: file_user_user_proto_depIdxs,
-		MessageInfos:      file_user_user_proto_msgTypes,
+		GoTypes:           file_traces_api_user_user_proto_goTypes,
+		DependencyIndexes: file_traces_api_user_user_proto_depIdxs,
+		MessageInfos:      file_traces_api_user_user_proto_msgTypes,
 	}.Build()
-	File_user_user_proto = out.File
-	file_user_user_proto_rawDesc = nil
-	file_user_user_proto_goTypes = nil
-	file_user_user_proto_depIdxs = nil
+	File_traces_api_user_user_proto = out.File
+	file_traces_api_user_user_proto_rawDesc = nil
+	file_traces_api_user_user_proto_goTypes = nil
+	file_traces_api_user_user_proto_depIdxs = nil
 }
diff --git a/examples/traces/api/user/user_grpc.pb.go b/examples/traces/api/user/user_grpc.pb.go
index 3960f2f1..53af844b 100644
--- a/examples/traces/api/user/user_grpc.pb.go
+++ b/examples/traces/api/user/user_grpc.pb.go
@@ -97,5 +97,5 @@ var User_ServiceDesc = grpc.ServiceDesc{
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "user/user.proto",
+	Metadata: "traces/api/user/user.proto",
 }
diff --git a/examples/traces/api/user/user_http.pb.go b/examples/traces/api/user/user_http.pb.go
index b4a48bf1..5d385cd0 100644
--- a/examples/traces/api/user/user_http.pb.go
+++ b/examples/traces/api/user/user_http.pb.go
@@ -4,6 +4,8 @@ package v1
 
 import (
 	context "context"
+	middleware "github.com/go-kratos/kratos/v2/middleware"
+	transport "github.com/go-kratos/kratos/v2/transport"
 	http1 "github.com/go-kratos/kratos/v2/transport/http"
 	binding "github.com/go-kratos/kratos/v2/transport/http/binding"
 	mux "github.com/gorilla/mux"
@@ -14,7 +16,9 @@ import (
 // is compatible with the kratos package it is being compiled against.
 var _ = new(http.Request)
 var _ = new(context.Context)
-var _ = binding.MapProto
+var _ = new(middleware.Middleware)
+var _ = new(transport.Transporter)
+var _ = binding.BindVars
 var _ = mux.NewRouter
 
 const _ = http1.SupportPackageIsVersion1
@@ -37,7 +41,7 @@ func NewUserHandler(srv UserHandler, opts ...http1.HandleOption) http.Handler {
 			return
 		}
 
-		if err := binding.MapProto(&in, mux.Vars(r)); err != nil {
+		if err := binding.BindVars(mux.Vars(r), &in); err != nil {
 			h.Error(w, r, err)
 			return
 		}
@@ -48,7 +52,9 @@ func NewUserHandler(srv UserHandler, opts ...http1.HandleOption) http.Handler {
 		if h.Middleware != nil {
 			next = h.Middleware(next)
 		}
-		out, err := next(r.Context(), &in)
+		ctx := r.Context()
+		transport.SetMethod(ctx, "/api.user.v1.User/GetMyMessages")
+		out, err := next(ctx, &in)
 		if err != nil {
 			h.Error(w, r, err)
 			return
@@ -61,3 +67,25 @@ func NewUserHandler(srv UserHandler, opts ...http1.HandleOption) http.Handler {
 
 	return r
 }
+
+type UserHTTPClient interface {
+	GetMyMessages(ctx context.Context, req *GetMyMessagesRequest, opts ...http1.CallOption) (rsp *GetMyMessagesReply, err error)
+}
+
+type UserHTTPClientImpl struct {
+	cc *http1.Client
+}
+
+func NewUserHTTPClient(client *http1.Client) UserHTTPClient {
+	return &UserHTTPClientImpl{client}
+}
+
+func (c *UserHTTPClientImpl) GetMyMessages(ctx context.Context, in *GetMyMessagesRequest, opts ...http1.CallOption) (*GetMyMessagesReply, error) {
+	var out GetMyMessagesReply
+	path := binding.EncodePath("GET", "/v1/user/get/message/{count}", in)
+	opts = append(opts, http1.Method("/api.user.v1.User/GetMyMessages"))
+
+	err := c.cc.Invoke(ctx, "GET", path, in, &out, opts...)
+
+	return &out, err
+}
diff --git a/examples/traces/app/message/main.go b/examples/traces/app/message/main.go
index 2e005f9a..64503f8d 100644
--- a/examples/traces/app/message/main.go
+++ b/examples/traces/app/message/main.go
@@ -2,6 +2,8 @@ package main
 
 import (
 	"context"
+	"os"
+
 	pb "github.com/go-kratos/kratos/examples/traces/api/message"
 	"github.com/go-kratos/kratos/v2"
 	"github.com/go-kratos/kratos/v2/log"
@@ -17,7 +19,6 @@ import (
 	tracesdk "go.opentelemetry.io/otel/sdk/trace"
 	"go.opentelemetry.io/otel/semconv"
 	"go.opentelemetry.io/otel/trace"
-	"os"
 )
 
 // go build -ldflags "-X main.Version=x.y.z"
@@ -58,14 +59,15 @@ func tracerProvider(url string) (*tracesdk.TracerProvider, error) {
 func (s *server) GetUserMessage(ctx context.Context, request *pb.GetUserMessageRequest) (*pb.GetUserMessageReply, error) {
 	msgs := &pb.GetUserMessageReply{}
 	for i := 0; i < int(request.Count); i++ {
-		msgs.Messages = append(msgs.Messages,&pb.Message{Content: "Teletubbies say hello."})
+		msgs.Messages = append(msgs.Messages, &pb.Message{Content: "Teletubbies say hello."})
 	}
 	return msgs, nil
 }
 
 func main() {
 	logger := log.NewStdLogger(os.Stdout)
-
+	logger = log.With(logger, "trace_id", log.TraceID())
+	logger = log.With(logger, "span_id", log.SpanID())
 	log := log.NewHelper(logger)
 
 	tp, err := tracerProvider("http://jaeger:14268/api/traces")
diff --git a/examples/traces/app/user/main.go b/examples/traces/app/user/main.go
index 53229b6a..d0837634 100644
--- a/examples/traces/app/user/main.go
+++ b/examples/traces/app/user/main.go
@@ -2,6 +2,9 @@ package main
 
 import (
 	"context"
+	"os"
+	"time"
+
 	message "github.com/go-kratos/kratos/examples/traces/api/message"
 	pb "github.com/go-kratos/kratos/examples/traces/api/user"
 	"github.com/go-kratos/kratos/v2"
@@ -19,8 +22,6 @@ import (
 	tracesdk "go.opentelemetry.io/otel/sdk/trace"
 	"go.opentelemetry.io/otel/semconv"
 	"go.opentelemetry.io/otel/trace"
-	"os"
-	"time"
 )
 
 // go build -ldflags "-X main.Version=x.y.z"
@@ -83,14 +84,15 @@ func (s *server) GetMyMessages(ctx context.Context, in *pb.GetMyMessagesRequest)
 	}
 	res := &pb.GetMyMessagesReply{}
 	for _, v := range reply.Messages {
-		res.Messages = append(res.Messages,&pb.Message{Content: v.Content})
+		res.Messages = append(res.Messages, &pb.Message{Content: v.Content})
 	}
 	return res, nil
 }
 
 func main() {
 	logger := log.NewStdLogger(os.Stdout)
-
+	logger = log.With(logger, "trace_id", log.TraceID())
+	logger = log.With(logger, "span_id", log.SpanID())
 	log := log.NewHelper(logger)
 
 	tp, err := tracerProvider("http://jaeger:14268/api/traces")
diff --git a/metadata/metadata.go b/metadata/metadata.go
new file mode 100644
index 00000000..445886fb
--- /dev/null
+++ b/metadata/metadata.go
@@ -0,0 +1,67 @@
+package metadata
+
+import (
+	"strings"
+)
+
+// Metadata is our way of representing request headers internally.
+// They're used at the RPC level and translate back and forth
+// from Transport headers.
+type Metadata map[string]string
+
+// New creates an MD from a given key-values map.
+func New(m map[string][]string) Metadata {
+	md := Metadata{}
+	for k, v := range m {
+		if k == "" {
+			continue
+		}
+		key := strings.ToLower(k)
+		if len(v) > 0 && v[0] != "" {
+			md[key] = v[0]
+		}
+	}
+	return md
+}
+
+// Get returns the value associated with the passed key.
+func (m Metadata) Get(key string) string {
+	k := strings.ToLower(key)
+	return m[k]
+}
+
+// Set stores the key-value pair.
+func (m Metadata) Set(key string, value string) {
+	if key == "" || value == "" {
+		return
+	}
+	k := strings.ToLower(key)
+	m[k] = value
+}
+
+// Keys lists the keys stored in this carrier.
+func (m Metadata) Keys() []string {
+	keys := make([]string, 0, len(m))
+	for k := range m {
+		keys = append(keys, k)
+	}
+	return keys
+}
+
+// Pairs returns all metadata to key/value pairs.
+func (m Metadata) Pairs() []string {
+	var kvs = make([]string, 0, len(m)*2)
+	for k, v := range m {
+		kvs = append(kvs, k, v)
+	}
+	return kvs
+}
+
+// Clone returns a deep copy of Metadata
+func (m Metadata) Clone() Metadata {
+	md := Metadata{}
+	for k, v := range m {
+		md[k] = v
+	}
+	return md
+}
diff --git a/middleware/logging/grpc.go b/middleware/logging/grpc.go
deleted file mode 100644
index 66b41ba6..00000000
--- a/middleware/logging/grpc.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package logging
-
-import (
-	"context"
-
-	"github.com/go-kratos/kratos/v2/errors"
-	"github.com/go-kratos/kratos/v2/internal/httputil"
-	"github.com/go-kratos/kratos/v2/log"
-	"github.com/go-kratos/kratos/v2/transport/grpc"
-)
-
-// grpcServerLog is a server handler when transport is KindGRPC
-func grpcServerLog(logger log.Logger, ctx context.Context, args string, err error) {
-	info, ok := grpc.FromServerContext(ctx)
-	if !ok {
-		return
-	}
-
-	level := log.LevelInfo
-	if err != nil {
-		level = log.LevelError
-	}
-
-	log.WithContext(ctx, logger).Log(level,
-		"kind", "server",
-		"component", "grpc",
-		"grpc.target", info.FullMethod,
-		"grpc.args", args,
-		"grpc.code", httputil.GRPCCodeFromStatus(errors.Code(err)),
-		"grpc.error", extractError(err),
-	)
-}
-
-// grpcClientLog is a client handler when transport is KindGRPC
-func grpcClientLog(logger log.Logger, ctx context.Context, args string, err error) {
-	info, ok := grpc.FromClientContext(ctx)
-	if !ok {
-		return
-	}
-	level := log.LevelInfo
-	if err != nil {
-		level = log.LevelError
-	}
-	log.WithContext(ctx, logger).Log(level,
-		"kind", "client",
-		"component", "grpc",
-		"grpc.target", info.FullMethod,
-		"grpc.args", args,
-		"grpc.code", httputil.GRPCCodeFromStatus(errors.Code(err)),
-		"grpc.error", extractError(err),
-	)
-}
diff --git a/middleware/logging/http.go b/middleware/logging/http.go
deleted file mode 100644
index a8b64775..00000000
--- a/middleware/logging/http.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package logging
-
-import (
-	"context"
-
-	"github.com/go-kratos/kratos/v2/errors"
-	"github.com/go-kratos/kratos/v2/log"
-	"github.com/go-kratos/kratos/v2/transport/http"
-)
-
-// httpServerLog is a middleware server handler when transport is KindHTTP
-func httpServerLog(logger log.Logger, ctx context.Context, args string, err error) {
-	info, ok := http.FromServerContext(ctx)
-	if !ok {
-		return
-	}
-
-	level := log.LevelInfo
-	if err != nil {
-		level = log.LevelError
-	}
-
-	log.WithContext(ctx, logger).Log(level,
-		"kind", "server",
-		"component", "http",
-		"http.target", info.Request.RequestURI,
-		"http.method", info.Request.Method,
-		"http.args", args,
-		"http.code", errors.Code(err),
-		"http.error", extractError(err),
-	)
-}
-
-// httpClientLog is a middleware client handler when transport is KindHTTP
-func httpClientLog(logger log.Logger, ctx context.Context, args string, err error) {
-	info, ok := http.FromClientContext(ctx)
-	if !ok {
-		return
-	}
-
-	level := log.LevelInfo
-	if err != nil {
-		level = log.LevelError
-	}
-
-	log.WithContext(ctx, logger).Log(level,
-		"kind", "client",
-		"component", "http",
-		"http.target", info.Request.RequestURI,
-		"http.method", info.Request.Method,
-		"http.args", args,
-		"http.code", errors.Code(err),
-		"http.error", extractError(err),
-	)
-}
diff --git a/middleware/logging/logging.go b/middleware/logging/logging.go
index 5dd58efa..65623c47 100644
--- a/middleware/logging/logging.go
+++ b/middleware/logging/logging.go
@@ -3,7 +3,9 @@ package logging
 import (
 	"context"
 	"fmt"
+	"time"
 
+	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
@@ -13,15 +15,33 @@ import (
 func Server(logger log.Logger) middleware.Middleware {
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
+			var (
+				code   int32
+				reason string
+				kind   string
+				method string
+			)
+			startTime := time.Now()
+			if info, ok := transport.FromServerContext(ctx); ok {
+				kind = info.Kind()
+				method = info.Method()
+			}
 			reply, err = handler(ctx, req)
-			if tr, ok := transport.FromContext(ctx); ok {
-				switch tr.Kind {
-				case transport.KindHTTP:
-					httpServerLog(logger, ctx, extractArgs(req), err)
-				case transport.KindGRPC:
-					grpcServerLog(logger, ctx, extractArgs(req), err)
-				}
+			if se := errors.FromError(err); se != nil {
+				code = se.Code
+				reason = se.Reason
 			}
+			level, stack := extractError(err)
+			log.WithContext(ctx, logger).Log(level,
+				"kind", "server",
+				"component", kind,
+				"method", method,
+				"args", extractArgs(req),
+				"code", code,
+				"reason", reason,
+				"stack", stack,
+				"latency", time.Since(startTime).Seconds(),
+			)
 			return
 		}
 	}
@@ -31,15 +51,33 @@ func Server(logger log.Logger) middleware.Middleware {
 func Client(logger log.Logger) middleware.Middleware {
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
+			var (
+				code   int32
+				reason string
+				kind   string
+				method string
+			)
+			startTime := time.Now()
+			if info, ok := transport.FromClientContext(ctx); ok {
+				kind = info.Kind()
+				method = info.Method()
+			}
 			reply, err = handler(ctx, req)
-			if tr, ok := transport.FromContext(ctx); ok {
-				switch tr.Kind {
-				case transport.KindHTTP:
-					httpClientLog(logger, ctx, extractArgs(req), err)
-				case transport.KindGRPC:
-					grpcClientLog(logger, ctx, extractArgs(req), err)
-				}
+			if se := errors.FromError(err); se != nil {
+				code = se.Code
+				reason = se.Reason
 			}
+			level, stack := extractError(err)
+			log.WithContext(ctx, logger).Log(level,
+				"kind", "client",
+				"component", kind,
+				"method", method,
+				"args", extractArgs(req),
+				"code", code,
+				"reason", reason,
+				"stack", stack,
+				"latency", time.Since(startTime).Seconds(),
+			)
 			return
 		}
 	}
@@ -54,9 +92,9 @@ func extractArgs(req interface{}) string {
 }
 
 // extractError returns the string of the error
-func extractError(err error) (errMsg string) {
+func extractError(err error) (log.Level, string) {
 	if err != nil {
-		errMsg = fmt.Sprintf("%+v", err)
+		return log.LevelError, fmt.Sprintf("%+v", err)
 	}
-	return
+	return log.LevelInfo, ""
 }
diff --git a/middleware/metrics/metrics.go b/middleware/metrics/metrics.go
index 3982f36a..d7b08e51 100644
--- a/middleware/metrics/metrics.go
+++ b/middleware/metrics/metrics.go
@@ -6,12 +6,9 @@ import (
 	"time"
 
 	"github.com/go-kratos/kratos/v2/errors"
-	"github.com/go-kratos/kratos/v2/internal/httputil"
 	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/go-kratos/kratos/v2/middleware"
-	"github.com/go-kratos/kratos/v2/transport/grpc"
-	"github.com/go-kratos/kratos/v2/transport/http"
-	"github.com/gorilla/mux"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 // Option is metrics option.
@@ -32,9 +29,9 @@ func WithSeconds(c metrics.Observer) Option {
 }
 
 type options struct {
-	// counter: <kind>_<client/server>_requests_code_total{method, path, code, reason}
+	// counter: <client/server>_requests_code_total{kind, method, code, reason}
 	requests metrics.Counter
-	// histogram: <kind>_<client/server>_requests_seconds_bucket{method, path}
+	// histogram: <client/server>_requests_seconds_bucket{kind, method}
 	seconds metrics.Observer
 }
 
@@ -47,37 +44,28 @@ func Server(opts ...Option) middleware.Middleware {
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (interface{}, error) {
 			var (
+				code   int
+				reason string
+				kind   string
 				method string
-				path   string
-				code   uint32
 			)
 			startTime := time.Now()
+			if info, ok := transport.FromServerContext(ctx); ok {
+				kind = info.Kind()
+				method = info.Method()
+			}
 			reply, err := handler(ctx, req)
-
-			if info, ok := grpc.FromServerContext(ctx); ok {
-				method = "POST"
-				path = info.FullMethod
-				code = uint32(httputil.GRPCCodeFromStatus(errors.Code(err)))
-			} else if info, ok := http.FromServerContext(ctx); ok {
-				req := info.Request.WithContext(ctx)
-				method = req.Method
-				if route := mux.CurrentRoute(req); route != nil {
-					// /path/123 -> /path/{id}
-					path, _ = route.GetPathTemplate()
-				} else {
-					path = req.RequestURI
-				}
-				code = uint32(errors.Code(err))
+			if se := errors.FromError(err); se != nil {
+				code = int(se.Code)
+				reason = se.Reason
 			}
-
 			if options.requests != nil {
-				options.requests.With(method, path, strconv.Itoa(int(code)), errors.Reason(err)).Inc()
+				options.requests.With(kind, method, strconv.Itoa(code), reason).Inc()
 			}
 			if options.seconds != nil {
-				options.seconds.With(method, path).Observe(time.Since(startTime).Seconds())
+				options.seconds.With(kind, method).Observe(time.Since(startTime).Seconds())
 			}
 			return reply, err
-
 		}
 	}
 }
@@ -91,28 +79,26 @@ func Client(opts ...Option) middleware.Middleware {
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (interface{}, error) {
 			var (
+				code   int
+				reason string
+				kind   string
 				method string
-				path   string
-				code   uint32
 			)
 			startTime := time.Now()
+			if info, ok := transport.FromClientContext(ctx); ok {
+				kind = info.Kind()
+				method = info.Method()
+			}
 			reply, err := handler(ctx, req)
-
-			if info, ok := grpc.FromClientContext(ctx); ok {
-				method = "POST"
-				path = info.FullMethod
-				code = uint32(httputil.GRPCCodeFromStatus(errors.Code(err)))
-			} else if info, ok := http.FromClientContext(ctx); ok {
-				method = info.Request.Method
-				path = info.Request.RequestURI
-				code = uint32(errors.Code(err))
+			if se := errors.FromError(err); se != nil {
+				code = int(se.Code)
+				reason = se.Reason
 			}
-
 			if options.requests != nil {
-				options.requests.With(method, path, strconv.Itoa(int(code)), errors.Reason(err)).Inc()
+				options.requests.With(kind, method, strconv.Itoa(code), reason).Inc()
 			}
 			if options.seconds != nil {
-				options.seconds.With(method, path).Observe(time.Since(startTime).Seconds())
+				options.seconds.With(kind, method).Observe(time.Since(startTime).Seconds())
 			}
 			return reply, err
 		}
diff --git a/middleware/tracing/carrier.go b/middleware/tracing/carrier.go
deleted file mode 100644
index ebc58f0c..00000000
--- a/middleware/tracing/carrier.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package tracing
-
-import (
-	"google.golang.org/grpc/metadata"
-)
-
-// MetadataCarrier is grpc metadata carrier
-type MetadataCarrier metadata.MD
-
-// Get returns the value associated with the passed key.
-func (mc MetadataCarrier) Get(key string) string {
-	values := metadata.MD(mc).Get(key)
-	if len(values) == 0 {
-		return ""
-	}
-	return values[0]
-}
-
-// Set stores the key-value pair.
-func (mc MetadataCarrier) Set(key string, value string) {
-	metadata.MD(mc).Set(key, value)
-}
-
-// Keys lists the keys stored in this carrier.
-func (mc MetadataCarrier) Keys() []string {
-	keys := make([]string, 0, metadata.MD(mc).Len())
-	for key := range metadata.MD(mc) {
-		keys = append(keys, key)
-	}
-	return keys
-}
-
-// Del delete key
-func (mc MetadataCarrier) Del(key string) {
-	delete(mc, key)
-}
-
-// Clone copy MetadataCarrier
-func (mc MetadataCarrier) Clone() MetadataCarrier {
-	return MetadataCarrier(metadata.MD(mc).Copy())
-}
diff --git a/middleware/tracing/tracer.go b/middleware/tracing/tracer.go
index c7d695b6..7a35c887 100644
--- a/middleware/tracing/tracer.go
+++ b/middleware/tracing/tracer.go
@@ -31,16 +31,14 @@ func NewTracer(kind trace.SpanKind, opts ...Option) *Tracer {
 	} else {
 		otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{}, propagation.TraceContext{}))
 	}
-	var name string
-	if kind == trace.SpanKindServer {
-		name = "server"
-	} else if kind == trace.SpanKindClient {
-		name = "client"
-	} else {
+	switch kind {
+	case trace.SpanKindClient:
+		return &Tracer{tracer: otel.Tracer("client"), kind: kind}
+	case trace.SpanKindServer:
+		return &Tracer{tracer: otel.Tracer("server"), kind: kind}
+	default:
 		panic(fmt.Sprintf("unsupported span kind: %v", kind))
 	}
-	tracer := otel.Tracer(name)
-	return &Tracer{tracer: tracer, kind: kind}
 }
 
 // Start start tracing span
diff --git a/middleware/tracing/tracing.go b/middleware/tracing/tracing.go
index de15c386..ed16b7e9 100644
--- a/middleware/tracing/tracing.go
+++ b/middleware/tracing/tracing.go
@@ -4,12 +4,9 @@ import (
 	"context"
 
 	"github.com/go-kratos/kratos/v2/middleware"
-	"github.com/go-kratos/kratos/v2/transport/grpc"
-	"github.com/go-kratos/kratos/v2/transport/http"
-	"go.opentelemetry.io/otel"
+	"github.com/go-kratos/kratos/v2/transport"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/trace"
-	"google.golang.org/grpc/metadata"
 )
 
 // Option is tracing option.
@@ -20,12 +17,14 @@ type options struct {
 	Propagators    propagation.TextMapPropagator
 }
 
+// WithPropagators with tracer proagators.
 func WithPropagators(propagators propagation.TextMapPropagator) Option {
 	return func(opts *options) {
 		opts.Propagators = propagators
 	}
 }
 
+// WithTracerProvider with tracer privoder.
 func WithTracerProvider(provider trace.TracerProvider) Option {
 	return func(opts *options) {
 		opts.TracerProvider = provider
@@ -35,34 +34,14 @@ func WithTracerProvider(provider trace.TracerProvider) Option {
 // Server returns a new server middleware for OpenTelemetry.
 func Server(opts ...Option) middleware.Middleware {
 	tracer := NewTracer(trace.SpanKindServer, opts...)
-
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
-			var (
-				component string
-				operation string
-				carrier   propagation.TextMapCarrier
-			)
-			if info, ok := http.FromServerContext(ctx); ok {
-				// HTTP span
-				component = "HTTP"
-				operation = info.Request.RequestURI
-				carrier = propagation.HeaderCarrier(info.Request.Header)
-				ctx = otel.GetTextMapPropagator().Extract(ctx, propagation.HeaderCarrier(info.Request.Header))
-			} else if info, ok := grpc.FromServerContext(ctx); ok {
-				// gRPC span
-				component = "gRPC"
-				operation = info.FullMethod
-				if md, ok := metadata.FromIncomingContext(ctx); ok {
-					carrier = MetadataCarrier(md)
-				}
+			if tr, ok := transport.FromServerContext(ctx); ok {
+				var span trace.Span
+				ctx, span = tracer.Start(ctx, tr.Kind(), tr.Method(), tr.Metadata())
+				defer func() { tracer.End(ctx, span, err) }()
 			}
-			ctx, span := tracer.Start(ctx, component, operation, carrier)
-			defer func() { tracer.End(ctx, span, err) }()
-
-			reply, err = handler(ctx, req)
-
-			return
+			return handler(ctx, req)
 		}
 	}
 }
@@ -70,36 +49,14 @@ func Server(opts ...Option) middleware.Middleware {
 // Client returns a new client middleware for OpenTelemetry.
 func Client(opts ...Option) middleware.Middleware {
 	tracer := NewTracer(trace.SpanKindClient, opts...)
-
 	return func(handler middleware.Handler) middleware.Handler {
 		return func(ctx context.Context, req interface{}) (reply interface{}, err error) {
-			var (
-				component string
-				operation string
-				carrier   propagation.TextMapCarrier
-			)
-			if info, ok := http.FromClientContext(ctx); ok {
-				// HTTP span
-				component = "HTTP"
-				operation = info.Request.RequestURI
-				carrier = propagation.HeaderCarrier(info.Request.Header)
-			} else if info, ok := grpc.FromClientContext(ctx); ok {
-				// gRPC span
-				component = "gRPC"
-				operation = info.FullMethod
-				md, ok := metadata.FromOutgoingContext(ctx)
-				if !ok {
-					md = metadata.Pairs()
-				}
-				carrier = MetadataCarrier(md)
-				ctx = metadata.NewOutgoingContext(ctx, md)
+			if tr, ok := transport.FromClientContext(ctx); ok {
+				var span trace.Span
+				ctx, span = tracer.Start(ctx, tr.Kind(), tr.Method(), tr.Metadata())
+				defer func() { tracer.End(ctx, span, err) }()
 			}
-			ctx, span := tracer.Start(ctx, component, operation, carrier)
-			defer func() { tracer.End(ctx, span, err) }()
-
-			reply, err = handler(ctx, req)
-
-			return
+			return handler(ctx, req)
 		}
 	}
 }
diff --git a/transport/grpc/client.go b/transport/grpc/client.go
index e5f37c9b..18af330b 100644
--- a/transport/grpc/client.go
+++ b/transport/grpc/client.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"time"
 
+	"github.com/go-kratos/kratos/v2/metadata"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/go-kratos/kratos/v2/transport"
@@ -14,6 +15,7 @@ import (
 
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/balancer/roundrobin"
+	grpcmd "google.golang.org/grpc/metadata"
 )
 
 // ClientOption is gRPC client option.
@@ -112,14 +114,20 @@ func dial(ctx context.Context, insecure bool, opts ...ClientOption) (*grpc.Clien
 
 func unaryClientInterceptor(m middleware.Middleware, timeout time.Duration) grpc.UnaryClientInterceptor {
 	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
-		ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindGRPC, Endpoint: cc.Target()})
-		ctx = NewClientContext(ctx, ClientInfo{FullMethod: method})
+		ctx = transport.NewClientContext(ctx, &Transport{
+			endpoint: cc.Target(),
+			method:   method,
+			metadata: metadata.Metadata{},
+		})
 		if timeout > 0 {
 			var cancel context.CancelFunc
 			ctx, cancel = context.WithTimeout(ctx, timeout)
 			defer cancel()
 		}
 		h := func(ctx context.Context, req interface{}) (interface{}, error) {
+			if tr, ok := transport.FromClientContext(ctx); ok {
+				ctx = grpcmd.AppendToOutgoingContext(ctx, tr.Metadata().Pairs()...)
+			}
 			return reply, invoker(ctx, method, req, reply, cc, opts...)
 		}
 		if m != nil {
diff --git a/transport/grpc/context.go b/transport/grpc/context.go
deleted file mode 100644
index 2708c56a..00000000
--- a/transport/grpc/context.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package grpc
-
-import (
-	"context"
-)
-
-// ServerInfo represent gRPC server information.
-type ServerInfo struct {
-	// Server is the service implementation the user provides. This is read-only.
-	Server interface{}
-	// FullMethod is the full RPC method string, i.e., /package.service/method.
-	FullMethod string
-}
-
-type serverKey struct{}
-
-// NewServerContext returns a new Context that carries value.
-func NewServerContext(ctx context.Context, info ServerInfo) context.Context {
-	return context.WithValue(ctx, serverKey{}, info)
-}
-
-// FromServerContext returns the Transport value stored in ctx, if any.
-func FromServerContext(ctx context.Context) (info ServerInfo, ok bool) {
-	info, ok = ctx.Value(serverKey{}).(ServerInfo)
-	return
-}
-
-// ClientInfo represent gRPC server information.
-type ClientInfo struct {
-	// FullMethod is the full RPC method string, i.e., /package.service/method.
-	FullMethod string
-}
-
-type clientKey struct{}
-
-// NewClientContext returns a new Context that carries value.
-func NewClientContext(ctx context.Context, info ClientInfo) context.Context {
-	return context.WithValue(ctx, clientKey{}, info)
-}
-
-// FromClientContext returns the Transport value stored in ctx, if any.
-func FromClientContext(ctx context.Context) (info ClientInfo, ok bool) {
-	info, ok = ctx.Value(clientKey{}).(ClientInfo)
-	return
-}
diff --git a/transport/grpc/server.go b/transport/grpc/server.go
index af76ea0f..74cfe97b 100644
--- a/transport/grpc/server.go
+++ b/transport/grpc/server.go
@@ -7,15 +7,18 @@ import (
 	"sync"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/api/metadata"
+	apimd "github.com/go-kratos/kratos/v2/api/metadata"
 	ic "github.com/go-kratos/kratos/v2/internal/context"
 	"github.com/go-kratos/kratos/v2/internal/host"
 	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/metadata"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
+
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/health"
 	"google.golang.org/grpc/health/grpc_health_v1"
+	grpcmd "google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/reflection"
 )
 
@@ -90,7 +93,7 @@ type Server struct {
 	ints       []grpc.UnaryServerInterceptor
 	grpcOpts   []grpc.ServerOption
 	health     *health.Server
-	metadata   *metadata.Server
+	metadata   *apimd.Server
 }
 
 // NewServer creates a gRPC server by options.
@@ -118,10 +121,10 @@ func NewServer(opts ...ServerOption) *Server {
 		grpcOpts = append(grpcOpts, srv.grpcOpts...)
 	}
 	srv.Server = grpc.NewServer(grpcOpts...)
-	srv.metadata = metadata.NewServer(srv.Server)
+	srv.metadata = apimd.NewServer(srv.Server)
 	// internal register
 	grpc_health_v1.RegisterHealthServer(srv.Server, srv.health)
-	metadata.RegisterMetadataServer(srv.Server, srv.metadata)
+	apimd.RegisterMetadataServer(srv.Server, srv.metadata)
 	reflection.Register(srv.Server)
 	return srv
 }
@@ -174,8 +177,12 @@ func (s *Server) unaryServerInterceptor() grpc.UnaryServerInterceptor {
 	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
 		ctx, cancel := ic.Merge(ctx, s.ctx)
 		defer cancel()
-		ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindGRPC, Endpoint: s.endpoint.String()})
-		ctx = NewServerContext(ctx, ServerInfo{Server: info.Server, FullMethod: info.FullMethod})
+		md, _ := grpcmd.FromIncomingContext(ctx)
+		ctx = transport.NewServerContext(ctx, &Transport{
+			endpoint: s.endpoint.String(),
+			method:   info.FullMethod,
+			metadata: metadata.New(md),
+		})
 		if s.timeout > 0 {
 			var cancel context.CancelFunc
 			ctx, cancel = context.WithTimeout(ctx, s.timeout)
diff --git a/transport/grpc/transport.go b/transport/grpc/transport.go
new file mode 100644
index 00000000..91bc3eed
--- /dev/null
+++ b/transport/grpc/transport.go
@@ -0,0 +1,53 @@
+package grpc
+
+import (
+	"github.com/go-kratos/kratos/v2/metadata"
+	"github.com/go-kratos/kratos/v2/transport"
+)
+
+var (
+	_ transport.Transporter = &Transport{}
+)
+
+// Transport is a gRPC transport.
+type Transport struct {
+	endpoint string
+	method   string
+	metadata metadata.Metadata
+}
+
+// Kind returns the transport kind.
+func (tr *Transport) Kind() string {
+	return "grpc"
+}
+
+// Endpoint returns the transport endpoint.
+func (tr *Transport) Endpoint() string {
+	return tr.endpoint
+}
+
+// Method returns the transport method.
+func (tr *Transport) Method() string {
+	return tr.method
+}
+
+// SetMethod sets the transport method.
+func (tr *Transport) SetMethod(method string) {
+	tr.method = method
+}
+
+// Metadata returns the transport metadata.
+func (tr *Transport) Metadata() metadata.Metadata {
+	return tr.metadata
+}
+
+// WithMetadata with a metadata into transport md.
+func (tr *Transport) WithMetadata(md metadata.Metadata) {
+	if tr.metadata == nil {
+		tr.metadata = md
+		return
+	}
+	for k, v := range md {
+		tr.metadata.Set(k, v)
+	}
+}
diff --git a/transport/http/balancer/balancer.go b/transport/http/balancer/balancer.go
index db252954..8964c1a5 100644
--- a/transport/http/balancer/balancer.go
+++ b/transport/http/balancer/balancer.go
@@ -14,5 +14,5 @@ type DoneInfo struct {
 
 // Balancer is node pick balancer
 type Balancer interface {
-	Pick(ctx context.Context, pathPattern string, nodes []*registry.ServiceInstance) (node *registry.ServiceInstance, done func(context.Context, DoneInfo), err error)
+	Pick(ctx context.Context, nodes []*registry.ServiceInstance) (node *registry.ServiceInstance, done func(context.Context, DoneInfo), err error)
 }
diff --git a/transport/http/balancer/random/random.go b/transport/http/balancer/random/random.go
index 9ac93c8d..b0c741e6 100644
--- a/transport/http/balancer/random/random.go
+++ b/transport/http/balancer/random/random.go
@@ -18,7 +18,7 @@ func New() *Balancer {
 	return &Balancer{}
 }
 
-func (b *Balancer) Pick(ctx context.Context, pathPattern string, nodes []*registry.ServiceInstance) (node *registry.ServiceInstance, done func(context.Context, balancer.DoneInfo), err error) {
+func (b *Balancer) Pick(ctx context.Context, nodes []*registry.ServiceInstance) (node *registry.ServiceInstance, done func(context.Context, balancer.DoneInfo), err error) {
 	if len(nodes) == 0 {
 		return nil, nil, fmt.Errorf("no instances avaiable")
 	}
diff --git a/transport/http/binding/bind.go b/transport/http/binding/bind.go
index 2d0b5a5b..b8f8f4c4 100644
--- a/transport/http/binding/bind.go
+++ b/transport/http/binding/bind.go
@@ -28,9 +28,3 @@ func BindVars(vars map[string]string, target interface{}) error {
 	}
 	return mapForm(target, values)
 }
-
-// BindValue bind map parameters to target.
-// Deprecated: use BindVars instead.
-func BindValue(vars map[string]string, target interface{}) error {
-	return BindVars(vars, target)
-}
diff --git a/transport/http/binding/proto.go b/transport/http/binding/proto.go
index a56d693c..6425600e 100644
--- a/transport/http/binding/proto.go
+++ b/transport/http/binding/proto.go
@@ -17,17 +17,6 @@ import (
 	"google.golang.org/protobuf/types/known/wrapperspb"
 )
 
-// MapProto sets a value in a nested Protobuf structure.
-// Deprecated: use BindValue instead.
-func MapProto(msg proto.Message, values map[string]string) error {
-	for key, value := range values {
-		if err := populateFieldValues(msg.ProtoReflect(), strings.Split(key, "."), []string{value}); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
 func mapProto(msg proto.Message, values map[string][]string) error {
 	for key, values := range values {
 		if err := populateFieldValues(msg.ProtoReflect(), strings.Split(key, "."), values); err != nil {
diff --git a/transport/http/calloption.go b/transport/http/calloption.go
index b794859b..840ada85 100644
--- a/transport/http/calloption.go
+++ b/transport/http/calloption.go
@@ -1,5 +1,7 @@
 package http
 
+import "github.com/go-kratos/kratos/v2/metadata"
+
 // CallOption configures a Call before it starts or extracts information from
 // a Call after it completes.
 type CallOption interface {
@@ -13,8 +15,9 @@ type CallOption interface {
 }
 
 type callInfo struct {
-	pathPattern string
+	contentType string
 	method      string
+	metatada    metadata.Metadata
 }
 
 // EmptyCallOption does not alter the Call configuration.
@@ -27,28 +30,36 @@ func (EmptyCallOption) after(*callInfo, *csAttempt) {}
 
 type csAttempt struct{}
 
-// PathPattern is pathpattern
-func PathPattern(pathPattern string) CallOption {
-	return PathPatternCallOption{PathPattern: pathPattern}
+// ContentType with request content type.
+func ContentType(contentType string) CallOption {
+	return ContentTypeCallOption{ContentType: contentType}
 }
 
-// PathPatternCallOption is BodyPattern
-type PathPatternCallOption struct {
+// ContentTypeCallOption is BodyCallOption
+type ContentTypeCallOption struct {
 	EmptyCallOption
-	PathPattern string
+	ContentType string
 }
 
-func (o PathPatternCallOption) before(c *callInfo) error {
-	c.pathPattern = o.PathPattern
+func (o ContentTypeCallOption) before(c *callInfo) error {
+	c.contentType = o.ContentType
 	return nil
 }
 
-// Method is Method
+func defaultCallInfo(path string) callInfo {
+	return callInfo{
+		contentType: "application/json",
+		method:      path,
+		metatada:    metadata.Metadata{},
+	}
+}
+
+// Method is serviceMethod call option
 func Method(method string) CallOption {
 	return MethodCallOption{Method: method}
 }
 
-// MethodCallOption is BodyCallOption
+// MethodCallOption is set ServiceMethod for client call
 type MethodCallOption struct {
 	EmptyCallOption
 	Method string
@@ -59,8 +70,18 @@ func (o MethodCallOption) before(c *callInfo) error {
 	return nil
 }
 
-func defaultCallInfo() callInfo {
-	return callInfo{
-		method: "POST",
-	}
+// Metadata is Metadata call option
+func Metadata(metatada metadata.Metadata) CallOption {
+	return MetadataCallOption{Metatada: metatada}
+}
+
+// MetadataCallOption is set Metadata for client call
+type MetadataCallOption struct {
+	EmptyCallOption
+	Metatada metadata.Metadata
+}
+
+func (o MetadataCallOption) before(c *callInfo) error {
+	c.metatada = o.Metatada
+	return nil
 }
diff --git a/transport/http/client.go b/transport/http/client.go
index 73682dce..4f5cf6b3 100644
--- a/transport/http/client.go
+++ b/transport/http/client.go
@@ -12,6 +12,7 @@ import (
 	"github.com/go-kratos/kratos/v2/encoding"
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/httputil"
+	"github.com/go-kratos/kratos/v2/metadata"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/go-kratos/kratos/v2/transport"
@@ -23,7 +24,7 @@ import (
 type DecodeErrorFunc func(ctx context.Context, res *http.Response) error
 
 // EncodeRequestFunc is request encode func.
-type EncodeRequestFunc func(ctx context.Context, in interface{}) (contentType string, body []byte, err error)
+type EncodeRequestFunc func(ctx context.Context, contentType string, in interface{}) (body []byte, err error)
 
 // DecodeResponseFunc is response decode func.
 type DecodeResponseFunc func(ctx context.Context, res *http.Response, out interface{}) error
@@ -166,41 +167,44 @@ func NewClient(ctx context.Context, opts ...ClientOption) (*Client, error) {
 }
 
 // Invoke makes an rpc call procedure for remote service.
-func (client *Client) Invoke(ctx context.Context, path string, args interface{}, reply interface{}, opts ...CallOption) error {
+func (client *Client) Invoke(ctx context.Context, method, path string, args interface{}, reply interface{}, opts ...CallOption) error {
 	var (
-		reqBody     io.Reader
 		contentType string
+		body        io.Reader
 	)
-	c := defaultCallInfo()
+	c := defaultCallInfo(path)
 	for _, o := range opts {
 		if err := o.before(&c); err != nil {
 			return err
 		}
 	}
 	if args != nil {
-		var (
-			body []byte
-			err  error
-		)
-		contentType, body, err = client.opts.encoder(ctx, args)
+		data, err := client.opts.encoder(ctx, c.contentType, args)
 		if err != nil {
 			return err
 		}
-		reqBody = bytes.NewReader(body)
+		contentType = c.contentType
+		body = bytes.NewReader(data)
 	}
 	url := fmt.Sprintf("%s://%s%s", client.target.Scheme, client.target.Authority, path)
-	req, err := http.NewRequest(c.method, url, reqBody)
+	req, err := http.NewRequest(method, url, body)
 	if err != nil {
 		return err
 	}
 	if contentType != "" {
-		req.Header.Set("Content-Type", contentType)
+		req.Header.Set("Content-Type", c.contentType)
 	}
 	if client.opts.userAgent != "" {
 		req.Header.Set("User-Agent", client.opts.userAgent)
 	}
-	ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindHTTP, Endpoint: client.opts.endpoint})
-	ctx = NewClientContext(ctx, ClientInfo{PathPattern: c.pathPattern, Request: req})
+	if c.metatada == nil {
+		c.metatada = metadata.Metadata{}
+	}
+	ctx = transport.NewClientContext(ctx, &Transport{
+		endpoint: client.opts.endpoint,
+		metadata: c.metatada,
+		method:   c.method,
+	})
 	return client.invoke(ctx, req, args, reply, c)
 }
 
@@ -213,7 +217,7 @@ func (client *Client) invoke(ctx context.Context, req *http.Request, args interf
 				node  *registry.ServiceInstance
 				nodes = client.r.fetch(ctx)
 			)
-			if node, done, err = client.opts.balancer.Pick(ctx, c.pathPattern, nodes); err != nil {
+			if node, done, err = client.opts.balancer.Pick(ctx, nodes); err != nil {
 				return nil, errors.ServiceUnavailable("NODE_NOT_FOUND", err.Error())
 			}
 			scheme, addr, err := parseEndpoint(node.Endpoints)
@@ -224,6 +228,11 @@ func (client *Client) invoke(ctx context.Context, req *http.Request, args interf
 			req.URL.Scheme = scheme
 			req.URL.Host = addr
 		}
+		if tr, ok := transport.FromClientContext(ctx); ok {
+			for _, key := range tr.Metadata().Keys() {
+				req.Header.Set(key, tr.Metadata().Get(key))
+			}
+		}
 		res, err := client.do(ctx, req, c)
 		if done != nil {
 			done(ctx, balancer.DoneInfo{Err: err})
@@ -247,7 +256,7 @@ func (client *Client) invoke(ctx context.Context, req *http.Request, args interf
 // Do send an HTTP request and decodes the body of response into target.
 // returns an error (of type *Error) if the response status code is not 2xx.
 func (client *Client) Do(req *http.Request, opts ...CallOption) (*http.Response, error) {
-	c := defaultCallInfo()
+	c := defaultCallInfo(req.URL.Path)
 	for _, o := range opts {
 		if err := o.before(&c); err != nil {
 			return nil, err
@@ -268,12 +277,13 @@ func (client *Client) do(ctx context.Context, req *http.Request, c callInfo) (*h
 }
 
 // DefaultRequestEncoder is an HTTP request encoder.
-func DefaultRequestEncoder(ctx context.Context, in interface{}) (string, []byte, error) {
-	body, err := encoding.GetCodec("json").Marshal(in)
+func DefaultRequestEncoder(ctx context.Context, contentType string, in interface{}) ([]byte, error) {
+	name := httputil.ContentSubtype(contentType)
+	body, err := encoding.GetCodec(name).Marshal(in)
 	if err != nil {
-		return "", nil, err
+		return nil, err
 	}
-	return "application/json", body, err
+	return body, err
 }
 
 // DefaultResponseDecoder is an HTTP response decoder.
diff --git a/transport/http/context.go b/transport/http/context.go
deleted file mode 100644
index e8bab4a8..00000000
--- a/transport/http/context.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package http
-
-import (
-	"context"
-	"net/http"
-)
-
-// ServerInfo represent HTTP server information.
-type ServerInfo struct {
-	Request  *http.Request
-	Response http.ResponseWriter
-}
-
-type serverKey struct{}
-
-// NewServerContext returns a new Context that carries value.
-func NewServerContext(ctx context.Context, info ServerInfo) context.Context {
-	return context.WithValue(ctx, serverKey{}, info)
-}
-
-// FromServerContext returns the Transport value stored in ctx, if any.
-func FromServerContext(ctx context.Context) (info ServerInfo, ok bool) {
-	info, ok = ctx.Value(serverKey{}).(ServerInfo)
-	return
-}
-
-// ClientInfo represent HTTP client information.
-type ClientInfo struct {
-	Request     *http.Request
-	PathPattern string
-}
-
-type clientKey struct{}
-
-// NewClientContext returns a new Context that carries value.
-func NewClientContext(ctx context.Context, info ClientInfo) context.Context {
-	return context.WithValue(ctx, clientKey{}, info)
-}
-
-// FromClientContext returns the Transport value stored in ctx, if any.
-func FromClientContext(ctx context.Context) (info ClientInfo, ok bool) {
-	info, ok = ctx.Value(clientKey{}).(ClientInfo)
-	return
-}
diff --git a/transport/http/server.go b/transport/http/server.go
index 302d4f10..fbe21d2c 100644
--- a/transport/http/server.go
+++ b/transport/http/server.go
@@ -12,6 +12,7 @@ import (
 	ic "github.com/go-kratos/kratos/v2/internal/context"
 	"github.com/go-kratos/kratos/v2/internal/host"
 	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/metadata"
 	"github.com/go-kratos/kratos/v2/transport"
 
 	"github.com/gorilla/mux"
@@ -101,8 +102,11 @@ func (s *Server) HandleFunc(path string, h http.HandlerFunc) {
 func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
 	ctx, cancel := ic.Merge(req.Context(), s.ctx)
 	defer cancel()
-	ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindHTTP, Endpoint: s.endpoint.String()})
-	ctx = NewServerContext(ctx, ServerInfo{Request: req, Response: res})
+	ctx = transport.NewServerContext(ctx, &Transport{
+		endpoint: s.endpoint.String(),
+		method:   req.RequestURI,
+		metadata: metadata.New(req.Header),
+	})
 	if s.timeout > 0 {
 		ctx, cancel = context.WithTimeout(ctx, s.timeout)
 		defer cancel()
diff --git a/transport/http/transport.go b/transport/http/transport.go
new file mode 100644
index 00000000..e2e3f46d
--- /dev/null
+++ b/transport/http/transport.go
@@ -0,0 +1,53 @@
+package http
+
+import (
+	"github.com/go-kratos/kratos/v2/metadata"
+	"github.com/go-kratos/kratos/v2/transport"
+)
+
+var (
+	_ transport.Transporter = &Transport{}
+)
+
+// Transport is an HTTP transport.
+type Transport struct {
+	endpoint string
+	method   string
+	metadata metadata.Metadata
+}
+
+// Kind returns the transport kind.
+func (tr *Transport) Kind() string {
+	return "http"
+}
+
+// Endpoint returns the transport endpoint.
+func (tr *Transport) Endpoint() string {
+	return tr.endpoint
+}
+
+// Method returns the transport method.
+func (tr *Transport) Method() string {
+	return tr.method
+}
+
+// SetMethod sets the transport method.
+func (tr *Transport) SetMethod(method string) {
+	tr.method = method
+}
+
+// Metadata returns the transport metadata.
+func (tr *Transport) Metadata() metadata.Metadata {
+	return tr.metadata
+}
+
+// WithMetadata with a metadata into transport md.
+func (tr *Transport) WithMetadata(md metadata.Metadata) {
+	if tr.metadata == nil {
+		tr.metadata = md
+		return
+	}
+	for k, v := range md {
+		tr.metadata.Set(k, v)
+	}
+}
diff --git a/transport/transport.go b/transport/transport.go
index 51a5af0b..3e2995a9 100644
--- a/transport/transport.go
+++ b/transport/transport.go
@@ -9,6 +9,7 @@ import (
 	_ "github.com/go-kratos/kratos/v2/encoding/proto"
 	_ "github.com/go-kratos/kratos/v2/encoding/xml"
 	_ "github.com/go-kratos/kratos/v2/encoding/yaml"
+	"github.com/go-kratos/kratos/v2/metadata"
 )
 
 // Server is transport server.
@@ -22,30 +23,71 @@ type Endpointer interface {
 	Endpoint() (*url.URL, error)
 }
 
-// Transport is transport context value.
-type Transport struct {
-	Kind     Kind
-	Endpoint string
+// Transporter is transport context value interface.
+type Transporter interface {
+	Kind() string
+	Endpoint() string
+
+	Method() string
+	SetMethod(string)
+
+	Metadata() metadata.Metadata
+	// WithMetadata merge new metadata into transport,
+	// it will override old metadata key value if key exists
+	WithMetadata(metadata.Metadata)
 }
 
-// Kind defines the type of Transport
-type Kind string
+type serverTransportKey struct{}
+type clientTransportKey struct{}
 
-// Defines a set of transport kind
-const (
-	KindGRPC Kind = "gRPC"
-	KindHTTP Kind = "HTTP"
-)
+// NewServerContext returns a new Context that carries value.
+func NewServerContext(ctx context.Context, tr Transporter) context.Context {
+	return context.WithValue(ctx, serverTransportKey{}, tr)
+}
 
-type transportKey struct{}
+// FromServerContext returns the Transport value stored in ctx, if any.
+func FromServerContext(ctx context.Context) (tr Transporter, ok bool) {
+	tr, ok = ctx.Value(serverTransportKey{}).(Transporter)
+	return
+}
 
-// NewContext returns a new Context that carries value.
-func NewContext(ctx context.Context, tr Transport) context.Context {
-	return context.WithValue(ctx, transportKey{}, tr)
+// NewClientContext returns a new Context that carries value.
+func NewClientContext(ctx context.Context, tr Transporter) context.Context {
+	return context.WithValue(ctx, clientTransportKey{}, tr)
 }
 
-// FromContext returns the Transport value stored in ctx, if any.
-func FromContext(ctx context.Context) (tr Transport, ok bool) {
-	tr, ok = ctx.Value(transportKey{}).(Transport)
+// FromClientContext returns the Transport value stored in ctx, if any.
+func FromClientContext(ctx context.Context) (tr Transporter, ok bool) {
+	tr, ok = ctx.Value(clientTransportKey{}).(Transporter)
 	return
 }
+
+// Method returns the Transport method from server context.
+func Method(ctx context.Context) string {
+	if tr, ok := FromServerContext(ctx); ok {
+		return tr.Method()
+	}
+	return ""
+}
+
+// SetMethod set serviceMethod into context transport.
+func SetMethod(ctx context.Context, method string) {
+	if tr, ok := FromServerContext(ctx); ok {
+		tr.SetMethod(method)
+	}
+}
+
+// Metadata returns incoming metadata from server transport.
+func Metadata(ctx context.Context) metadata.Metadata {
+	if tr, ok := FromServerContext(ctx); ok {
+		return tr.Metadata()
+	}
+	return metadata.Metadata{}
+}
+
+// SetMetadata sets outgoing metadata into client transport.
+func SetMetadata(ctx context.Context, md metadata.Metadata) {
+	if tr, ok := FromClientContext(ctx); ok {
+		tr.WithMetadata(md)
+	}
+}


Test patch:
diff --git a/middleware/logging/logging_test.go b/middleware/logging/logging_test.go
index 66b266ee..335677e8 100644
--- a/middleware/logging/logging_test.go
+++ b/middleware/logging/logging_test.go
@@ -4,17 +4,49 @@ import (
 	"bytes"
 	"context"
 	"errors"
-	"net/http/httptest"
 	"testing"
 
 	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/metadata"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
-	"github.com/go-kratos/kratos/v2/transport/http"
 )
 
+var (
+	_ transport.Transporter = &Transport{}
+)
+
+type Transport struct {
+	kind     string
+	endpoint string
+	method   string
+}
+
+func (tr *Transport) Kind() string {
+	return tr.kind
+}
+
+func (tr *Transport) Endpoint() string {
+	return tr.endpoint
+}
+
+func (tr *Transport) Method() string {
+	return tr.method
+}
+
+func (tr *Transport) SetMethod(method string) {
+	tr.method = method
+}
+
+func (tr *Transport) Metadata() metadata.Metadata {
+	return nil
+}
+
+func (tr *Transport) WithMetadata(md metadata.Metadata) {
+
+}
+
 func TestHTTP(t *testing.T) {
-	var req = httptest.NewRequest("GET", "http://example.com/foo", nil)
 	var err = errors.New("reply.error")
 	var bf = bytes.NewBuffer(nil)
 	var logger = log.NewStdLogger(bf)
@@ -29,34 +61,29 @@ func TestHTTP(t *testing.T) {
 			Server,
 			err,
 			func() context.Context {
-				res := httptest.NewRecorder()
-				ctx := transport.NewContext(context.Background(), transport.Transport{Kind: transport.KindHTTP, Endpoint: "endpoint"})
-				return http.NewServerContext(ctx, http.ServerInfo{Request: req, Response: res})
+				return transport.NewServerContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
 			}(),
 		},
 		{"http-server@succ",
 			Server,
 			nil,
 			func() context.Context {
-				res := httptest.NewRecorder()
-				ctx := transport.NewContext(context.Background(), transport.Transport{Kind: transport.KindHTTP, Endpoint: "endpoint"})
-				return http.NewServerContext(ctx, http.ServerInfo{Request: req, Response: res})
+				return transport.NewServerContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
 			}(),
 		},
 		{"http-client@succ",
 			Client,
 			nil,
 			func() context.Context {
-				ctx := transport.NewContext(context.Background(), transport.Transport{Kind: transport.KindHTTP, Endpoint: "endpoint"})
-				return http.NewClientContext(ctx, http.ClientInfo{Request: req, PathPattern: "{name}"})
+				return transport.NewClientContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
+
 			}(),
 		},
 		{"http-client@fail",
 			Client,
 			err,
 			func() context.Context {
-				ctx := transport.NewContext(context.Background(), transport.Transport{Kind: transport.KindHTTP, Endpoint: "endpoint"})
-				return http.NewClientContext(ctx, http.ClientInfo{Request: req, PathPattern: "{name}"})
+				return transport.NewClientContext(context.Background(), &Transport{kind: "http", endpoint: "endpoint", method: "/package.service/method"})
 			}(),
 		},
 	}
@@ -70,7 +97,7 @@ func TestHTTP(t *testing.T) {
 			next = test.kind(logger)(next)
 			v, e := next(test.ctx, "req.args")
 			t.Logf("[%s]reply: %v, error: %v", test.name, v, e)
-			t.Logf("[%s]buffer:%s", test.name, bf.String())
+			t.Logf("[%s]log:%s", test.name, bf.String())
 		})
 	}
 }
diff --git a/transport/http/server_test.go b/transport/http/server_test.go
index 90da0969..78296160 100644
--- a/transport/http/server_test.go
+++ b/transport/http/server_test.go
@@ -93,7 +93,7 @@ func testClient(t *testing.T, srv *Server) {
 	}
 	for _, test := range tests {
 		var res testData
-		err := client.Invoke(context.Background(), test.path, nil, &res, Method(test.method))
+		err := client.Invoke(context.Background(), test.method, test.path, nil, &res)
 		if err != nil {
 			t.Fatalf("invoke  error %v", err)
 		}