Repository: go-kratos/kratos
Pull request #2393 (2022-09-20 14:14:28)

cleanup: remove the repeated import
<!--
🎉 Thanks for sending a pull request to Kratos! Here are some tips for you:

1. If this is your first time contributing to Kratos, please read our contribution guide: https://go-kratos.dev/en/docs/community/contribution/
2. Ensure you have added or ran the appropriate tests and lint for your PR, please use `make lint` and `make test` before filing your PR, use `make clean` to tidy your go mod.
3. If the PR is unfinished, you may need to mark it as a WIP(Work In Progress) PR or draft PR
4. Please use a semantic commits format title, such as `<type>[optional scope]: <description>`, see: https://go-kratos.dev/docs/community/contribution#type
5. at the same time, please note that similar work should be submitted in one PR as far as possible to reduce the workload of reviewers. Do not split a work into multiple PR unless it should.
-->

<!--
🎉 感谢您向 Kratos 发送 PR 请求！以下是一些提示：
如果这是你第一次为 Kratos 贡献，请阅读我们的贡献指南：https://go-kratos.dev/en/docs/community/contribution/
2、确保您已经为您的 PR 添加或运行了适当的测试和lint，请在提交PR之前使用“make lint”和“make test”，使用“make clean”整理您的 go.mod。
3、如果请购单未完成，您可能需要将其标记为 WIP（在制品）PR 或 draft PR
4、请使用语义提交格式标题，如“<类型>[可选范围]：<说明>`，请参阅：https://go-kratos.dev/docs/community/contribution#type
5. 同时请注意，同类的工作请尽量在一个PR中提交，以减轻 review 者的工作负担，不要把一项工作拆分成很多个PR，除非它应该这样做。
-->

<!--
-->

#### Description (what this PR does / why we need it):
<!--
* The description should include the motivation for this PR or contrast this with previous behavior
-->


#### Which issue(s) this PR fixes (resolves / be part of):
<!--
* Automatically closes linked issue when PR is merged.
* If your PR is not fully resolved the issue, please use `part of #<issue number>` instead.

Usage: `fixes/resolves #<issue number>`, or `fixes/resolves (paste link of issue)`.
-->


#### Other special notes for the reviewers:
<!--
* Somethings that need extra attention for the reviewers
* Some additional notes, TODO list, etc.
-->



Patch:
diff --git a/api/metadata/server.go b/api/metadata/server.go
index 96f0e1e6..39e468ec 100644
--- a/api/metadata/server.go
+++ b/api/metadata/server.go
@@ -9,7 +9,6 @@ import (
 	"io"
 	"sync"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
@@ -18,6 +17,8 @@ import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	"google.golang.org/protobuf/reflect/protoregistry"
 	dpb "google.golang.org/protobuf/types/descriptorpb"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 // Server is api meta server
diff --git a/cmd/kratos/internal/project/add.go b/cmd/kratos/internal/project/add.go
index f4c1b88c..9f30bfcb 100644
--- a/cmd/kratos/internal/project/add.go
+++ b/cmd/kratos/internal/project/add.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/AlecAivazis/survey/v2"
 	"github.com/fatih/color"
+
 	"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
 )
 
diff --git a/cmd/kratos/internal/project/project.go b/cmd/kratos/internal/project/project.go
index 8ea7f2a9..271ad373 100644
--- a/cmd/kratos/internal/project/project.go
+++ b/cmd/kratos/internal/project/project.go
@@ -9,8 +9,9 @@ import (
 	"time"
 
 	"github.com/AlecAivazis/survey/v2"
-	"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
 	"github.com/spf13/cobra"
+
+	"github.com/go-kratos/kratos/cmd/kratos/v2/internal/base"
 )
 
 // CmdNew represents the new command.
diff --git a/cmd/protoc-gen-go-errors/errors.go b/cmd/protoc-gen-go-errors/errors.go
index 6a097330..522c2968 100644
--- a/cmd/protoc-gen-go-errors/errors.go
+++ b/cmd/protoc-gen-go-errors/errors.go
@@ -8,9 +8,10 @@ import (
 	"golang.org/x/text/cases"
 	"golang.org/x/text/language"
 
-	"github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2/errors"
 	"google.golang.org/protobuf/compiler/protogen"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2/errors"
 )
 
 const (
diff --git a/config/file/watcher.go b/config/file/watcher.go
index 4c00b046..ea309fa8 100644
--- a/config/file/watcher.go
+++ b/config/file/watcher.go
@@ -6,6 +6,7 @@ import (
 	"path/filepath"
 
 	"github.com/fsnotify/fsnotify"
+
 	"github.com/go-kratos/kratos/v2/config"
 )
 
diff --git a/contrib/config/apollo/apollo.go b/contrib/config/apollo/apollo.go
index 5f868bab..259ed1a9 100644
--- a/contrib/config/apollo/apollo.go
+++ b/contrib/config/apollo/apollo.go
@@ -10,6 +10,7 @@ import (
 	"github.com/apolloconfig/agollo/v4/constant"
 	apolloConfig "github.com/apolloconfig/agollo/v4/env/config"
 	"github.com/apolloconfig/agollo/v4/extension"
+
 	"github.com/go-kratos/kratos/v2/encoding"
 )
 
diff --git a/contrib/config/consul/config.go b/contrib/config/consul/config.go
index f42611e0..dca8a88e 100644
--- a/contrib/config/consul/config.go
+++ b/contrib/config/consul/config.go
@@ -6,8 +6,9 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/hashicorp/consul/api"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 // Option is etcd config option.
diff --git a/contrib/config/consul/watcher.go b/contrib/config/consul/watcher.go
index baee9ef6..5c70d6f8 100644
--- a/contrib/config/consul/watcher.go
+++ b/contrib/config/consul/watcher.go
@@ -3,9 +3,10 @@ package consul
 import (
 	"context"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/hashicorp/consul/api"
 	"github.com/hashicorp/consul/api/watch"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type watcher struct {
diff --git a/contrib/config/etcd/config.go b/contrib/config/etcd/config.go
index 37059e10..76045a58 100644
--- a/contrib/config/etcd/config.go
+++ b/contrib/config/etcd/config.go
@@ -6,8 +6,9 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 // Option is etcd config option.
diff --git a/contrib/config/etcd/watcher.go b/contrib/config/etcd/watcher.go
index 388c2dd8..dd2ea911 100644
--- a/contrib/config/etcd/watcher.go
+++ b/contrib/config/etcd/watcher.go
@@ -3,8 +3,9 @@ package etcd
 import (
 	"context"
 
-	"github.com/go-kratos/kratos/v2/config"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type watcher struct {
diff --git a/contrib/config/kubernetes/config.go b/contrib/config/kubernetes/config.go
index c66b837f..12026fe8 100644
--- a/contrib/config/kubernetes/config.go
+++ b/contrib/config/kubernetes/config.go
@@ -7,12 +7,13 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 // Option is kubernetes option.
diff --git a/contrib/config/kubernetes/watcher.go b/contrib/config/kubernetes/watcher.go
index 87872b8d..c13a8a7e 100644
--- a/contrib/config/kubernetes/watcher.go
+++ b/contrib/config/kubernetes/watcher.go
@@ -4,10 +4,11 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/config"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/watch"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type watcher struct {
diff --git a/contrib/config/nacos/watcher.go b/contrib/config/nacos/watcher.go
index e190b688..fd528af7 100644
--- a/contrib/config/nacos/watcher.go
+++ b/contrib/config/nacos/watcher.go
@@ -5,8 +5,9 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/nacos-group/nacos-sdk-go/vo"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 type Watcher struct {
diff --git a/contrib/log/aliyun/aliyun.go b/contrib/log/aliyun/aliyun.go
index 1be5f764..390cb571 100644
--- a/contrib/log/aliyun/aliyun.go
+++ b/contrib/log/aliyun/aliyun.go
@@ -7,8 +7,9 @@ import (
 
 	sls "github.com/aliyun/aliyun-log-go-sdk"
 	"github.com/aliyun/aliyun-log-go-sdk/producer"
-	log "github.com/go-kratos/kratos/v2/log"
 	"google.golang.org/protobuf/proto"
+
+	log "github.com/go-kratos/kratos/v2/log"
 )
 
 // Logger see more detail https://github.com/aliyun/aliyun-log-go-sdk
@@ -159,6 +160,8 @@ func toString(v interface{}) string {
 		key = strconv.FormatUint(v, 10)
 	case string:
 		key = v
+	case bool:
+		key = strconv.FormatBool(v)
 	case []byte:
 		key = string(v)
 	default:
diff --git a/contrib/log/fluent/fluent.go b/contrib/log/fluent/fluent.go
index 07a15b86..86e86993 100644
--- a/contrib/log/fluent/fluent.go
+++ b/contrib/log/fluent/fluent.go
@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/fluent/fluent-logger-golang/fluent"
+
 	"github.com/go-kratos/kratos/v2/log"
 )
 
diff --git a/contrib/log/logrus/logrus.go b/contrib/log/logrus/logrus.go
index b08ba6e1..6fda38c5 100644
--- a/contrib/log/logrus/logrus.go
+++ b/contrib/log/logrus/logrus.go
@@ -1,8 +1,9 @@
 package logrus
 
 import (
-	"github.com/go-kratos/kratos/v2/log"
 	"github.com/sirupsen/logrus"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 var _ log.Logger = (*Logger)(nil)
diff --git a/contrib/log/tencent/tencent.go b/contrib/log/tencent/tencent.go
index 5d7267f2..40cc98cd 100644
--- a/contrib/log/tencent/tencent.go
+++ b/contrib/log/tencent/tencent.go
@@ -6,9 +6,10 @@ import (
 	"strconv"
 	"time"
 
-	log "github.com/go-kratos/kratos/v2/log"
 	cls "github.com/tencentcloud/tencentcloud-cls-sdk-go"
 	"google.golang.org/protobuf/proto"
+
+	log "github.com/go-kratos/kratos/v2/log"
 )
 
 type Logger interface {
diff --git a/contrib/log/zap/zap.go b/contrib/log/zap/zap.go
index 5929c486..511381f9 100644
--- a/contrib/log/zap/zap.go
+++ b/contrib/log/zap/zap.go
@@ -3,8 +3,9 @@ package zap
 import (
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"go.uber.org/zap"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 var _ log.Logger = (*Logger)(nil)
diff --git a/contrib/metrics/prometheus/counter.go b/contrib/metrics/prometheus/counter.go
index 8b90beab..5873c017 100644
--- a/contrib/metrics/prometheus/counter.go
+++ b/contrib/metrics/prometheus/counter.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Counter = (*counter)(nil)
diff --git a/contrib/metrics/prometheus/gauge.go b/contrib/metrics/prometheus/gauge.go
index 6df11d69..25750b6c 100644
--- a/contrib/metrics/prometheus/gauge.go
+++ b/contrib/metrics/prometheus/gauge.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Gauge = (*gauge)(nil)
diff --git a/contrib/metrics/prometheus/histogram.go b/contrib/metrics/prometheus/histogram.go
index 81b3b281..a0245d73 100644
--- a/contrib/metrics/prometheus/histogram.go
+++ b/contrib/metrics/prometheus/histogram.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Observer = (*histogram)(nil)
diff --git a/contrib/metrics/prometheus/summary.go b/contrib/metrics/prometheus/summary.go
index d8bcad91..25969edf 100644
--- a/contrib/metrics/prometheus/summary.go
+++ b/contrib/metrics/prometheus/summary.go
@@ -1,8 +1,9 @@
 package prometheus
 
 import (
-	"github.com/go-kratos/kratos/v2/metrics"
 	"github.com/prometheus/client_golang/prometheus"
+
+	"github.com/go-kratos/kratos/v2/metrics"
 )
 
 var _ metrics.Observer = (*summary)(nil)
diff --git a/contrib/registry/consul/client.go b/contrib/registry/consul/client.go
index 55425dff..c1364bb3 100644
--- a/contrib/registry/consul/client.go
+++ b/contrib/registry/consul/client.go
@@ -132,6 +132,8 @@ func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enab
 				Timeout:                        "5s",
 			})
 		}
+		// custom checks
+		asr.Checks = append(asr.Checks, c.serviceChecks...)
 	}
 	if c.heartbeat {
 		asr.Checks = append(asr.Checks, &api.AgentServiceCheck{
@@ -141,9 +143,6 @@ func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enab
 		})
 	}
 
-	// custom checks
-	asr.Checks = append(asr.Checks, c.serviceChecks...)
-
 	err := c.cli.Agent().ServiceRegister(asr)
 	if err != nil {
 		return err
diff --git a/contrib/registry/discovery/discovery.go b/contrib/registry/discovery/discovery.go
index 32f3f67c..f439b0ca 100644
--- a/contrib/registry/discovery/discovery.go
+++ b/contrib/registry/discovery/discovery.go
@@ -10,9 +10,10 @@ import (
 	"sync/atomic"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"github.com/go-resty/resty/v2"
 	"github.com/pkg/errors"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 type Discovery struct {
diff --git a/contrib/registry/etcd/registry.go b/contrib/registry/etcd/registry.go
index 76c114a0..5592f62d 100644
--- a/contrib/registry/etcd/registry.go
+++ b/contrib/registry/etcd/registry.go
@@ -6,8 +6,9 @@ import (
 	"math/rand"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var (
diff --git a/contrib/registry/etcd/watcher.go b/contrib/registry/etcd/watcher.go
index a5bf63c4..0e531a99 100644
--- a/contrib/registry/etcd/watcher.go
+++ b/contrib/registry/etcd/watcher.go
@@ -3,8 +3,9 @@ package etcd
 import (
 	"context"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var _ registry.Watcher = (*watcher)(nil)
diff --git a/contrib/registry/kubernetes/registry.go b/contrib/registry/kubernetes/registry.go
index 25390362..987ef1e1 100644
--- a/contrib/registry/kubernetes/registry.go
+++ b/contrib/registry/kubernetes/registry.go
@@ -11,7 +11,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	jsoniter "github.com/json-iterator/go"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -21,6 +20,8 @@ import (
 	"k8s.io/client-go/kubernetes"
 	listerv1 "k8s.io/client-go/listers/core/v1"
 	"k8s.io/client-go/tools/cache"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 // Defines the key name of specific fields
diff --git a/contrib/registry/nacos/watcher.go b/contrib/registry/nacos/watcher.go
index c5d652fc..78b4fc21 100644
--- a/contrib/registry/nacos/watcher.go
+++ b/contrib/registry/nacos/watcher.go
@@ -4,10 +4,11 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
 	"github.com/nacos-group/nacos-sdk-go/model"
 	"github.com/nacos-group/nacos-sdk-go/vo"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var _ registry.Watcher = (*watcher)(nil)
diff --git a/contrib/registry/servicecomb/registry.go b/contrib/registry/servicecomb/registry.go
index 7dd388c9..7a532396 100644
--- a/contrib/registry/servicecomb/registry.go
+++ b/contrib/registry/servicecomb/registry.go
@@ -7,7 +7,6 @@ import (
 	"time"
 
 	"github.com/go-chassis/cari/discovery"
-	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/go-chassis/sc-client"
 
@@ -114,7 +113,7 @@ func (r *Registry) Register(_ context.Context, svcIns *registry.ServiceInstance)
 			return parseErr
 		}
 		// 若错误码显示服务未注册，直接返回
-		if svcErr.Code != pb.ErrServiceAlreadyExists {
+		if svcErr.Code != discovery.ErrServiceAlreadyExists {
 			return err
 		}
 		sid, err = r.cli.GetMicroServiceID(appID, ms.ServiceName, ms.Version, ms.Environment)
diff --git a/contrib/registry/zookeeper/watcher.go b/contrib/registry/zookeeper/watcher.go
index f2009675..ddb98a84 100644
--- a/contrib/registry/zookeeper/watcher.go
+++ b/contrib/registry/zookeeper/watcher.go
@@ -6,8 +6,9 @@ import (
 	"path"
 	"sync/atomic"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/go-zookeeper/zk"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 var _ registry.Watcher = (*watcher)(nil)
diff --git a/encoding/form/form.go b/encoding/form/form.go
index 77c4237b..823aeb8f 100644
--- a/encoding/form/form.go
+++ b/encoding/form/form.go
@@ -17,10 +17,13 @@ const (
 	nullStr = "null"
 )
 
+var (
+	encoder = form.NewEncoder()
+	decoder = form.NewDecoder()
+)
+
 func init() {
-	decoder := form.NewDecoder()
 	decoder.SetTagName("json")
-	encoder := form.NewEncoder()
 	encoder.SetTagName("json")
 	encoding.RegisterCodec(codec{encoder: encoder, decoder: decoder})
 }
diff --git a/encoding/form/proto_encode.go b/encoding/form/proto_encode.go
index 449fca0d..28ebb0bc 100644
--- a/encoding/form/proto_encode.go
+++ b/encoding/form/proto_encode.go
@@ -14,16 +14,19 @@ import (
 )
 
 // EncodeValues encode a message into url values.
-func EncodeValues(msg proto.Message) (url.Values, error) {
+func EncodeValues(msg interface{}) (url.Values, error) {
 	if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
 		return url.Values{}, nil
 	}
-	u := make(url.Values)
-	err := encodeByField(u, "", msg.ProtoReflect())
-	if err != nil {
-		return nil, err
+	if v, ok := msg.(proto.Message); ok {
+		u := make(url.Values)
+		err := encodeByField(u, "", v.ProtoReflect())
+		if err != nil {
+			return nil, err
+		}
+		return u, nil
 	}
-	return u, nil
+	return encoder.Encode(msg)
 }
 
 func encodeByField(u url.Values, path string, m protoreflect.Message) (finalErr error) {
diff --git a/encoding/json/json.go b/encoding/json/json.go
index d5e020b7..c1982190 100644
--- a/encoding/json/json.go
+++ b/encoding/json/json.go
@@ -4,9 +4,10 @@ import (
 	"encoding/json"
 	"reflect"
 
-	"github.com/go-kratos/kratos/v2/encoding"
 	"google.golang.org/protobuf/encoding/protojson"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/v2/encoding"
 )
 
 // Name is the name registered for the json codec.
diff --git a/encoding/yaml/yaml.go b/encoding/yaml/yaml.go
index b2f885f0..1364b24c 100644
--- a/encoding/yaml/yaml.go
+++ b/encoding/yaml/yaml.go
@@ -1,8 +1,9 @@
 package yaml
 
 import (
-	"github.com/go-kratos/kratos/v2/encoding"
 	"gopkg.in/yaml.v3"
+
+	"github.com/go-kratos/kratos/v2/encoding"
 )
 
 // Name is the name registered for the yaml codec.
diff --git a/errors/errors.go b/errors/errors.go
index fd95ff3b..caf31cd3 100644
--- a/errors/errors.go
+++ b/errors/errors.go
@@ -4,9 +4,10 @@ import (
 	"errors"
 	"fmt"
 
-	httpstatus "github.com/go-kratos/kratos/v2/transport/http/status"
 	"google.golang.org/genproto/googleapis/rpc/errdetails"
 	"google.golang.org/grpc/status"
+
+	httpstatus "github.com/go-kratos/kratos/v2/transport/http/status"
 )
 
 const (
diff --git a/middleware/circuitbreaker/circuitbreaker.go b/middleware/circuitbreaker/circuitbreaker.go
index c7ab178e..31433ee7 100644
--- a/middleware/circuitbreaker/circuitbreaker.go
+++ b/middleware/circuitbreaker/circuitbreaker.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/go-kratos/aegis/circuitbreaker"
 	"github.com/go-kratos/aegis/circuitbreaker/sre"
+
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/group"
 	"github.com/go-kratos/kratos/v2/middleware"
diff --git a/middleware/ratelimit/ratelimit.go b/middleware/ratelimit/ratelimit.go
index 5bfae27b..23f21753 100644
--- a/middleware/ratelimit/ratelimit.go
+++ b/middleware/ratelimit/ratelimit.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/go-kratos/aegis/ratelimit"
 	"github.com/go-kratos/aegis/ratelimit/bbr"
+
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/middleware"
 )
diff --git a/middleware/tracing/metadata.go b/middleware/tracing/metadata.go
index 01e51132..7ad82806 100644
--- a/middleware/tracing/metadata.go
+++ b/middleware/tracing/metadata.go
@@ -3,9 +3,10 @@ package tracing
 import (
 	"context"
 
+	"go.opentelemetry.io/otel/propagation"
+
 	"github.com/go-kratos/kratos/v2"
 	"github.com/go-kratos/kratos/v2/metadata"
-	"go.opentelemetry.io/otel/propagation"
 )
 
 const serviceHeader = "x-md-service-name"
diff --git a/middleware/tracing/tracer.go b/middleware/tracing/tracer.go
index cf9115bb..798994f8 100644
--- a/middleware/tracing/tracer.go
+++ b/middleware/tracing/tracer.go
@@ -4,13 +4,14 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/go-kratos/kratos/v2/errors"
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/trace"
 	"google.golang.org/protobuf/proto"
+
+	"github.com/go-kratos/kratos/v2/errors"
 )
 
 // Tracer is otel span tracer
diff --git a/middleware/tracing/tracing.go b/middleware/tracing/tracing.go
index 167725f4..b89ce0a2 100644
--- a/middleware/tracing/tracing.go
+++ b/middleware/tracing/tracing.go
@@ -5,10 +5,11 @@ import (
 
 	"github.com/go-kratos/kratos/v2/log"
 
-	"github.com/go-kratos/kratos/v2/middleware"
-	"github.com/go-kratos/kratos/v2/transport"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/trace"
+
+	"github.com/go-kratos/kratos/v2/middleware"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 // Option is tracing option.
diff --git a/selector/default_node.go b/selector/default_node.go
index 186629e7..3554a3a1 100644
--- a/selector/default_node.go
+++ b/selector/default_node.go
@@ -6,6 +6,8 @@ import (
 	"github.com/go-kratos/kratos/v2/registry"
 )
 
+var _ Node = (*DefaultNode)(nil)
+
 // DefaultNode is selector node
 type DefaultNode struct {
 	scheme   string
diff --git a/selector/default_selector.go b/selector/default_selector.go
index 247af2e9..83b1ce9e 100644
--- a/selector/default_selector.go
+++ b/selector/default_selector.go
@@ -5,6 +5,11 @@ import (
 	"sync/atomic"
 )
 
+var (
+	_ Rebalancer = (*Default)(nil)
+	_ Builder    = (*DefaultBuilder)(nil)
+)
+
 // Default is composite selector.
 type Default struct {
 	NodeBuilder WeightedNodeBuilder
diff --git a/selector/node/direct/direct.go b/selector/node/direct/direct.go
index 62b30ed7..d32fc314 100644
--- a/selector/node/direct/direct.go
+++ b/selector/node/direct/direct.go
@@ -13,8 +13,8 @@ const (
 )
 
 var (
-	_ selector.WeightedNode        = &Node{}
-	_ selector.WeightedNodeBuilder = &Builder{}
+	_ selector.WeightedNode        = (*Node)(nil)
+	_ selector.WeightedNodeBuilder = (*Builder)(nil)
 )
 
 // Node is endpoint instance
diff --git a/selector/node/ewma/node.go b/selector/node/ewma/node.go
index 1707f108..4fed4aaa 100644
--- a/selector/node/ewma/node.go
+++ b/selector/node/ewma/node.go
@@ -21,8 +21,8 @@ const (
 )
 
 var (
-	_ selector.WeightedNode        = &Node{}
-	_ selector.WeightedNodeBuilder = &Builder{}
+	_ selector.WeightedNode        = (*Node)(nil)
+	_ selector.WeightedNodeBuilder = (*Builder)(nil)
 )
 
 // Node is endpoint instance
diff --git a/transport/grpc/codec.go b/transport/grpc/codec.go
index 19670bba..231f114f 100644
--- a/transport/grpc/codec.go
+++ b/transport/grpc/codec.go
@@ -3,10 +3,11 @@ package grpc
 import (
 	"fmt"
 
-	enc "github.com/go-kratos/kratos/v2/encoding"
-	"github.com/go-kratos/kratos/v2/encoding/json"
 	"google.golang.org/grpc/encoding"
 	"google.golang.org/protobuf/proto"
+
+	enc "github.com/go-kratos/kratos/v2/encoding"
+	"github.com/go-kratos/kratos/v2/encoding/json"
 )
 
 func init() {
diff --git a/transport/grpc/interceptor.go b/transport/grpc/interceptor.go
index ccd83ea6..6cc33154 100644
--- a/transport/grpc/interceptor.go
+++ b/transport/grpc/interceptor.go
@@ -3,11 +3,12 @@ package grpc
 import (
 	"context"
 
+	"google.golang.org/grpc"
+	grpcmd "google.golang.org/grpc/metadata"
+
 	ic "github.com/go-kratos/kratos/v2/internal/context"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
-	"google.golang.org/grpc"
-	grpcmd "google.golang.org/grpc/metadata"
 )
 
 // unaryServerInterceptor is a gRPC unary server interceptor
diff --git a/transport/grpc/transport.go b/transport/grpc/transport.go
index 866228d1..50ca5c91 100644
--- a/transport/grpc/transport.go
+++ b/transport/grpc/transport.go
@@ -1,9 +1,10 @@
 package grpc
 
 import (
+	"google.golang.org/grpc/metadata"
+
 	"github.com/go-kratos/kratos/v2/selector"
 	"github.com/go-kratos/kratos/v2/transport"
-	"google.golang.org/grpc/metadata"
 )
 
 var _ transport.Transporter = (*Transport)(nil)
diff --git a/transport/http/binding/encode.go b/transport/http/binding/encode.go
index 3129bbe5..9bcdbeef 100644
--- a/transport/http/binding/encode.go
+++ b/transport/http/binding/encode.go
@@ -1,75 +1,47 @@
 package binding
 
 import (
-	"fmt"
 	"reflect"
 	"regexp"
-	"strings"
 
 	"github.com/go-kratos/kratos/v2/encoding/form"
-
 	"google.golang.org/protobuf/proto"
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 )
 
-var reg = regexp.MustCompile(`/{[\\.\w]+}`)
+var reg = regexp.MustCompile(`{[\\.\w]+}`)
 
 // EncodeURL encode proto message to url path.
-func EncodeURL(pathTemplate string, msg proto.Message, needQuery bool) string {
+func EncodeURL(pathTemplate string, msg interface{}, needQuery bool) string {
 	if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
 		return pathTemplate
 	}
+	queryParams, _ := form.EncodeValues(msg)
 	pathParams := make(map[string]struct{})
 	path := reg.ReplaceAllStringFunc(pathTemplate, func(in string) string {
 		// it's unreachable because the reg means that must have more than one char in {}
 		//if len(in) < 4 { //nolint:gomnd // **  explain the 4 number here :-) **
 		//	return in
 		//}
-		key := in[2 : len(in)-1]
-		vars := strings.Split(key, ".")
-		value, err := getValueByField(msg.ProtoReflect(), vars)
-		if err != nil {
-			return in
-		}
+		key := in[1 : len(in)-1]
+		value := queryParams.Get(key)
 		pathParams[key] = struct{}{}
-		return "/" + value
+		return value
 	})
 	if !needQuery {
-		if query := form.EncodeFieldMask(msg.ProtoReflect()); query != "" {
-			return path + "?" + query
+		if v, ok := msg.(proto.Message); ok {
+			if query := form.EncodeFieldMask(v.ProtoReflect()); query != "" {
+				return path + "?" + query
+			}
 		}
 		return path
 	}
-	u, err := form.EncodeValues(msg)
-	if err == nil && len(u) > 0 {
+	if len(queryParams) > 0 {
 		for key := range pathParams {
-			delete(u, key)
+			delete(queryParams, key)
 		}
-		query := u.Encode()
-		if query != "" {
+		if query := queryParams.Encode(); query != "" {
 			path += "?" + query
 		}
 	}
 	return path
 }
-
-func getValueByField(v protoreflect.Message, fieldPath []string) (string, error) {
-	var fd protoreflect.FieldDescriptor
-	for i, fieldName := range fieldPath {
-		fields := v.Descriptor().Fields()
-		if fd = fields.ByJSONName(fieldName); fd == nil {
-			fd = fields.ByName(protoreflect.Name(fieldName))
-			if fd == nil {
-				return "", fmt.Errorf("field path not found: %q", fieldName)
-			}
-		}
-		if i == len(fieldPath)-1 {
-			break
-		}
-		if fd.Message() == nil || fd.Cardinality() == protoreflect.Repeated {
-			return "", fmt.Errorf("invalid path: %q is not a message", fieldName)
-		}
-		v = v.Get(fd).Message()
-	}
-	return form.EncodeField(fd, v.Get(fd))
-}
diff --git a/transport/http/context.go b/transport/http/context.go
index f65e03fb..347d7f2b 100644
--- a/transport/http/context.go
+++ b/transport/http/context.go
@@ -9,10 +9,11 @@ import (
 	"net/url"
 	"time"
 
+	"github.com/gorilla/mux"
+
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
 	"github.com/go-kratos/kratos/v2/transport/http/binding"
-	"github.com/gorilla/mux"
 )
 
 var _ Context = (*wrapper)(nil)


Test patch:
diff --git a/contrib/config/consul/config_test.go b/contrib/config/consul/config_test.go
index a82a2036..adb3c27c 100644
--- a/contrib/config/consul/config_test.go
+++ b/contrib/config/consul/config_test.go
@@ -5,8 +5,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/config"
 	"github.com/hashicorp/consul/api"
+
+	"github.com/go-kratos/kratos/v2/config"
 )
 
 const testPath = "kratos/test/config"
diff --git a/contrib/log/aliyun/aliyun_test.go b/contrib/log/aliyun/aliyun_test.go
index 1ceafc32..d7acf6bb 100644
--- a/contrib/log/aliyun/aliyun_test.go
+++ b/contrib/log/aliyun/aliyun_test.go
@@ -92,4 +92,8 @@ func TestLog(t *testing.T) {
 	if err != nil {
 		t.Errorf("Log() returns error:%v", err)
 	}
+	err = logger.Log(log.LevelDebug, true, 0)
+	if err != nil {
+		t.Errorf("Log() returns error:%v", err)
+	}
 }
diff --git a/contrib/log/logrus/logrus_test.go b/contrib/log/logrus/logrus_test.go
index 50b7a99b..45fe9da2 100644
--- a/contrib/log/logrus/logrus_test.go
+++ b/contrib/log/logrus/logrus_test.go
@@ -5,8 +5,9 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/log"
 	"github.com/sirupsen/logrus"
+
+	"github.com/go-kratos/kratos/v2/log"
 )
 
 func TestLoggerLog(t *testing.T) {
diff --git a/contrib/registry/consul/registry_test.go b/contrib/registry/consul/registry_test.go
index 483faf1a..6a1523c4 100644
--- a/contrib/registry/consul/registry_test.go
+++ b/contrib/registry/consul/registry_test.go
@@ -8,8 +8,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/hashicorp/consul/api"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func tcpServer(t *testing.T, lis net.Listener) {
diff --git a/contrib/registry/etcd/registry_test.go b/contrib/registry/etcd/registry_test.go
index 844d67ff..8fcecf94 100644
--- a/contrib/registry/etcd/registry_test.go
+++ b/contrib/registry/etcd/registry_test.go
@@ -8,8 +8,9 @@ import (
 
 	"google.golang.org/grpc"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	clientv3 "go.etcd.io/etcd/client/v3"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func TestRegistry(t *testing.T) {
diff --git a/contrib/registry/zookeeper/register_test.go b/contrib/registry/zookeeper/register_test.go
index 131f3ee1..a6f4515e 100644
--- a/contrib/registry/zookeeper/register_test.go
+++ b/contrib/registry/zookeeper/register_test.go
@@ -6,8 +6,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"github.com/go-zookeeper/zk"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func TestRegistry_GetService(t *testing.T) {
diff --git a/middleware/tracing/span_test.go b/middleware/tracing/span_test.go
index aad4614f..110dc6f5 100644
--- a/middleware/tracing/span_test.go
+++ b/middleware/tracing/span_test.go
@@ -7,13 +7,14 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
-	"github.com/go-kratos/kratos/v2/metadata"
-	"github.com/go-kratos/kratos/v2/transport"
 	"go.opentelemetry.io/otel/attribute"
 	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
 	"go.opentelemetry.io/otel/trace"
 	"google.golang.org/grpc/peer"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
+	"github.com/go-kratos/kratos/v2/metadata"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 func Test_parseFullMethod(t *testing.T) {
diff --git a/middleware/tracing/tracer_test.go b/middleware/tracing/tracer_test.go
index fbd51c07..af63844e 100644
--- a/middleware/tracing/tracer_test.go
+++ b/middleware/tracing/tracer_test.go
@@ -5,8 +5,9 @@ import (
 	"errors"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 	"go.opentelemetry.io/otel/trace"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 )
 
 func Test_NewTracer(t *testing.T) {
diff --git a/middleware/tracing/tracing_test.go b/middleware/tracing/tracing_test.go
index 222a6acc..b95771ab 100644
--- a/middleware/tracing/tracing_test.go
+++ b/middleware/tracing/tracing_test.go
@@ -7,11 +7,12 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/log"
-	"github.com/go-kratos/kratos/v2/transport"
 	"go.opentelemetry.io/otel/propagation"
 	tracesdk "go.opentelemetry.io/otel/sdk/trace"
 	"go.opentelemetry.io/otel/trace"
+
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/transport"
 )
 
 var _ transport.Transporter = (*mockTransport)(nil)
diff --git a/transport/grpc/balancer_test.go b/transport/grpc/balancer_test.go
index 5b700264..2dbb53bb 100644
--- a/transport/grpc/balancer_test.go
+++ b/transport/grpc/balancer_test.go
@@ -5,8 +5,9 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/selector"
 	"google.golang.org/grpc/metadata"
+
+	"github.com/go-kratos/kratos/v2/selector"
 )
 
 func TestTrailer(t *testing.T) {
diff --git a/transport/grpc/client_test.go b/transport/grpc/client_test.go
index d2540a7d..7ad55368 100644
--- a/transport/grpc/client_test.go
+++ b/transport/grpc/client_test.go
@@ -7,9 +7,10 @@ import (
 	"testing"
 	"time"
 
+	"google.golang.org/grpc"
+
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/registry"
-	"google.golang.org/grpc"
 )
 
 func TestWithEndpoint(t *testing.T) {
diff --git a/transport/grpc/resolver/discovery/builder_test.go b/transport/grpc/resolver/discovery/builder_test.go
index 770f12f1..664b5d44 100644
--- a/transport/grpc/resolver/discovery/builder_test.go
+++ b/transport/grpc/resolver/discovery/builder_test.go
@@ -7,9 +7,10 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"google.golang.org/grpc/resolver"
 	"google.golang.org/grpc/serviceconfig"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 func TestWithInsecure(t *testing.T) {
diff --git a/transport/grpc/resolver/discovery/resolver_test.go b/transport/grpc/resolver/discovery/resolver_test.go
index 33d9fc27..39ae400e 100644
--- a/transport/grpc/resolver/discovery/resolver_test.go
+++ b/transport/grpc/resolver/discovery/resolver_test.go
@@ -7,8 +7,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/go-kratos/kratos/v2/registry"
 	"google.golang.org/grpc/resolver"
+
+	"github.com/go-kratos/kratos/v2/registry"
 )
 
 type testClientConn struct {
diff --git a/transport/grpc/server_test.go b/transport/grpc/server_test.go
index fd1ae675..4db44fe9 100644
--- a/transport/grpc/server_test.go
+++ b/transport/grpc/server_test.go
@@ -11,12 +11,13 @@ import (
 	"testing"
 	"time"
 
+	"google.golang.org/grpc"
+
 	"github.com/go-kratos/kratos/v2/errors"
 	"github.com/go-kratos/kratos/v2/internal/matcher"
 	pb "github.com/go-kratos/kratos/v2/internal/testdata/helloworld"
 	"github.com/go-kratos/kratos/v2/middleware"
 	"github.com/go-kratos/kratos/v2/transport"
-	"google.golang.org/grpc"
 )
 
 // server is used to implement helloworld.GreeterServer.
diff --git a/transport/http/binding/encode_test.go b/transport/http/binding/encode_test.go
index fdc2bb78..7e8286c9 100644
--- a/transport/http/binding/encode_test.go
+++ b/transport/http/binding/encode_test.go
@@ -1,87 +1,139 @@
 package binding
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 	"google.golang.org/protobuf/types/known/fieldmaskpb"
+
+	"github.com/go-kratos/kratos/v2/internal/testdata/binding"
 )
 
 func TestProtoPath(t *testing.T) {
-	url := EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!"}}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/2233!!!` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", nil, false)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{}/sub/{sub.name}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}}, false)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{}/sub/hello" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{}/sub/{sub.name.cc}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}}, false)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{}/sub/{sub.name.cc}" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL(
-		"http://helloworld.Greeter/helloworld/{}/sub/{test_repeated.1}",
-		&binding.HelloRequest{
-			Name: "test", Sub: &binding.Sub{Name: "hello"},
-			TestRepeated: []string{"123", "456"},
-		},
-		false,
-	)
-	fmt.Println(url)
-	if url != "http://helloworld.Greeter/helloworld/{}/sub/{test_repeated.1}" {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "5566!!!"}}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/5566!!!` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/sub", &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!"}}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/sub` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}", &binding.HelloRequest{Name: "test"}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub/{sub.name33}", &binding.HelloRequest{Name: "test"}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/test/sub/{sub.name33}` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
-	}
-
-	url = EncodeURL("http://helloworld.Greeter/helloworld/{name}/sub", &binding.HelloRequest{
-		Name: "go",
-		Sub:  &binding.Sub{Name: "kratos"},
-	}, true)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/go/sub?sub.naming=kratos` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
+	tests := []struct {
+		pathTemplate string
+		request      *binding.HelloRequest
+		needQuery    bool
+		want         string
+	}{
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!!"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/2233!!!!",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+			request:      nil,
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/hello",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/hello",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{sub.name.cc}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/sub/{test_repeated}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "hello"}, TestRepeated: []string{"123", "456"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/sub/123",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "5566!!!"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/5566!!!",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/sub",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "2233!!!"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/sub",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}",
+			request:      &binding.HelloRequest{Name: "test"},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub/{sub.name}",
+			request:      &binding.HelloRequest{Name: "test"},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/test/sub/",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{name}/sub",
+			request:      &binding.HelloRequest{Name: "go", Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    true,
+			want:         "http://helloworld.Greeter/helloworld/go/sub?sub.naming=kratos",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/sub/{sub.naming}",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}, UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"name", "sub.naming"}}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/sub/kratos?updateMask=name,sub.naming",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/sub/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/sub/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/[{name}]/sub/[{sub.naming}]",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/[test]/sub/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/[{}]/sub/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/[{}]/sub/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/[{}]/sub/[{sub.naming}]/{[]}",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/[{}]/sub/[kratos]/{[]}",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{[sub]}/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{[sub]}/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{[name]}/[{sub.naming}]",
+			request:      &binding.HelloRequest{Name: "test", Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{[name]}/[kratos]",
+		},
+		{
+			pathTemplate: "http://helloworld.Greeter/helloworld/{}/[]/[{sub.naming}]",
+			request:      &binding.HelloRequest{Sub: &binding.Sub{Name: "kratos"}},
+			needQuery:    false,
+			want:         "http://helloworld.Greeter/helloworld/{}/[]/[kratos]",
+		},
 	}
 
-	url = EncodeURL("http://helloworld.Greeter/helloworld/sub/{sub.name}", &binding.HelloRequest{
-		Sub:        &binding.Sub{Name: "kratos"},
-		UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"name", "sub.name"}},
-	}, false)
-	fmt.Println(url)
-	if url != `http://helloworld.Greeter/helloworld/sub/kratos?updateMask=name,sub.name` {
-		t.Fatalf("proto path not expected!actual: %s ", url)
+	for _, test := range tests {
+		if EncodeURL(test.pathTemplate, test.request, test.needQuery) != test.want {
+			t.Fatalf("want: %s, got: %s", test.want, EncodeURL(test.pathTemplate, test.request, test.needQuery))
+		}
 	}
 }