From fea9106cf03c7440bac0d6cb044413abec493a30 Mon Sep 17 00:00:00 2001
From: Patrick <dreamlike.sky@foxmail.com>
Date: Sat, 14 Mar 2020 14:45:32 +0800
Subject: [PATCH] modify rest config

---
 common/extension/rest_config_reader.go        |  8 +-
 .../reader_impl}/default_config_reader.go     | 34 ++++----
 .../default_config_reader_test.go             |  8 +-
 .../reader_impl}/testdata/consumer_config.yml |  0
 .../reader_impl}/testdata/provider_config.yml |  0
 .../rest/config_reader}/rest_config_reader.go |  8 +-
 .../rest}/rest_config.go                      |  6 +-
 .../rest_config_loader.go                     | 80 +++++++++++++------
 .../rest_config_loader_test.go                | 12 +--
 protocol/rest/rest_interface/rest_server.go   |  5 +-
 protocol/rest/rest_invoker.go                 |  5 +-
 protocol/rest/rest_invoker_test.go            | 27 ++++---
 protocol/rest/rest_protocol.go                | 20 ++---
 protocol/rest/rest_protocol_test.go           | 18 ++---
 .../rest/rest_server/go_restful_server.go     | 11 +--
 15 files changed, 143 insertions(+), 99 deletions(-)
 rename {protocol/rest/rest_config_reader => config/rest/config_reader/reader_impl}/default_config_reader.go (64%)
 rename {protocol/rest/rest_config_reader => config/rest/config_reader/reader_impl}/default_config_reader_test.go (90%)
 rename {protocol/rest/rest_config_reader => config/rest/config_reader/reader_impl}/testdata/consumer_config.yml (100%)
 rename {protocol/rest/rest_config_reader => config/rest/config_reader/reader_impl}/testdata/provider_config.yml (100%)
 rename {protocol/rest/rest_interface => config/rest/config_reader}/rest_config_reader.go (82%)
 rename {protocol/rest/rest_interface => config/rest}/rest_config.go (97%)
 rename protocol/rest/rest_config_initializer.go => config/rest_config_loader.go (61%)
 rename protocol/rest/rest_config_initializer_test.go => config/rest_config_loader_test.go (88%)

diff --git a/common/extension/rest_config_reader.go b/common/extension/rest_config_reader.go
index 78451214e..1bd338cc2 100644
--- a/common/extension/rest_config_reader.go
+++ b/common/extension/rest_config_reader.go
@@ -18,18 +18,18 @@
 package extension
 
 import (
-	"github.com/apache/dubbo-go/protocol/rest/rest_interface"
+	"github.com/apache/dubbo-go/config/rest/config_reader"
 )
 
 var (
-	restConfigReaders = make(map[string]func() rest_interface.RestConfigReader)
+	restConfigReaders = make(map[string]func() config_reader.RestConfigReader)
 )
 
-func SetRestConfigReader(name string, fun func() rest_interface.RestConfigReader) {
+func SetRestConfigReader(name string, fun func() config_reader.RestConfigReader) {
 	restConfigReaders[name] = fun
 }
 
-func GetSingletonRestConfigReader(name string) rest_interface.RestConfigReader {
+func GetSingletonRestConfigReader(name string) config_reader.RestConfigReader {
 	if name == "" {
 		name = "default"
 	}
diff --git a/protocol/rest/rest_config_reader/default_config_reader.go b/config/rest/config_reader/reader_impl/default_config_reader.go
similarity index 64%
rename from protocol/rest/rest_config_reader/default_config_reader.go
rename to config/rest/config_reader/reader_impl/default_config_reader.go
index c0a100240..6f5780ba4 100644
--- a/protocol/rest/rest_config_reader/default_config_reader.go
+++ b/config/rest/config_reader/reader_impl/default_config_reader.go
@@ -15,9 +15,11 @@
  * limitations under the License.
  */
 
-package rest_config_reader
+package reader_impl
 
 import (
+	"github.com/apache/dubbo-go/config/rest"
+	"github.com/apache/dubbo-go/config/rest/config_reader"
 	"os"
 )
 
@@ -28,9 +30,7 @@ import (
 import (
 	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/common/extension"
-	"github.com/apache/dubbo-go/common/logger"
 	"github.com/apache/dubbo-go/common/yaml"
-	"github.com/apache/dubbo-go/protocol/rest/rest_interface"
 )
 
 var (
@@ -48,37 +48,35 @@ func NewDefaultConfigReader() *DefaultConfigReader {
 	return &DefaultConfigReader{}
 }
 
-func (dcr *DefaultConfigReader) ReadConsumerConfig() *rest_interface.RestConsumerConfig {
+func (dcr *DefaultConfigReader) ReadConsumerConfig() (*rest.RestConsumerConfig, error) {
 	confConFile := os.Getenv(constant.CONF_CONSUMER_FILE_PATH)
 	if len(confConFile) == 0 {
-		logger.Warnf("[Rest Config] rest consumer configure(consumer) file name is nil")
-		return nil
+		return nil, perrors.Errorf("[Rest Config] rest consumer configure(consumer) file name is nil")
 	}
-	restConsumerConfig := &rest_interface.RestConsumerConfig{}
+	restConsumerConfig := &rest.RestConsumerConfig{}
 	err := yaml.UnmarshalYMLConfig(confConFile, restConsumerConfig)
 	if err != nil {
-		logger.Errorf("[Rest Config] unmarshal Consumer RestYmlConfig error %v", perrors.WithStack(err))
-		return nil
+		return nil, perrors.Errorf("[Rest Config] unmarshal Consumer RestYmlConfig error %v", perrors.WithStack(err))
 	}
-	return restConsumerConfig
+	return restConsumerConfig, nil
 }
 
-func (dcr *DefaultConfigReader) ReadProviderConfig() *rest_interface.RestProviderConfig {
+func (dcr *DefaultConfigReader) ReadProviderConfig() (*rest.RestProviderConfig, error) {
 	confProFile := os.Getenv(constant.CONF_PROVIDER_FILE_PATH)
 	if len(confProFile) == 0 {
-		logger.Warnf("[Rest Config] rest provider configure(provider) file name is nil")
-		return nil
+		return nil, perrors.Errorf("[Rest Config] rest provider configure(provider) file name is nil")
+
 	}
-	restProviderConfig := &rest_interface.RestProviderConfig{}
+	restProviderConfig := &rest.RestProviderConfig{}
 	err := yaml.UnmarshalYMLConfig(confProFile, restProviderConfig)
 	if err != nil {
-		logger.Errorf("[Rest Config] unmarshal Provider RestYmlConfig error %v", perrors.WithStack(err))
-		return nil
+		return nil, perrors.Errorf("[Rest Config] unmarshal Provider RestYmlConfig error %v", perrors.WithStack(err))
+
 	}
-	return restProviderConfig
+	return restProviderConfig, nil
 }
 
-func GetDefaultConfigReader() rest_interface.RestConfigReader {
+func GetDefaultConfigReader() config_reader.RestConfigReader {
 	if defaultConfigReader == nil {
 		defaultConfigReader = NewDefaultConfigReader()
 	}
diff --git a/protocol/rest/rest_config_reader/default_config_reader_test.go b/config/rest/config_reader/reader_impl/default_config_reader_test.go
similarity index 90%
rename from protocol/rest/rest_config_reader/default_config_reader_test.go
rename to config/rest/config_reader/reader_impl/default_config_reader_test.go
index ec5384871..eca7436a1 100644
--- a/protocol/rest/rest_config_reader/default_config_reader_test.go
+++ b/config/rest/config_reader/reader_impl/default_config_reader_test.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package rest_config_reader
+package reader_impl
 
 import (
 	"os"
@@ -34,7 +34,8 @@ func TestDefaultConfigReader_ReadConsumerConfig(t *testing.T) {
 	err := os.Setenv(constant.CONF_CONSUMER_FILE_PATH, "./testdata/consumer_config.yml")
 	assert.NoError(t, err)
 	reader := GetDefaultConfigReader()
-	config := reader.ReadConsumerConfig()
+	config, err := reader.ReadConsumerConfig()
+	assert.Nil(t, err)
 	assert.NotEmpty(t, config)
 }
 
@@ -42,6 +43,7 @@ func TestDefaultConfigReader_ReadProviderConfig(t *testing.T) {
 	err := os.Setenv(constant.CONF_PROVIDER_FILE_PATH, "./testdata/provider_config.yml")
 	assert.NoError(t, err)
 	reader := GetDefaultConfigReader()
-	config := reader.ReadProviderConfig()
+	config, err := reader.ReadProviderConfig()
+	assert.Nil(t, err)
 	assert.NotEmpty(t, config)
 }
diff --git a/protocol/rest/rest_config_reader/testdata/consumer_config.yml b/config/rest/config_reader/reader_impl/testdata/consumer_config.yml
similarity index 100%
rename from protocol/rest/rest_config_reader/testdata/consumer_config.yml
rename to config/rest/config_reader/reader_impl/testdata/consumer_config.yml
diff --git a/protocol/rest/rest_config_reader/testdata/provider_config.yml b/config/rest/config_reader/reader_impl/testdata/provider_config.yml
similarity index 100%
rename from protocol/rest/rest_config_reader/testdata/provider_config.yml
rename to config/rest/config_reader/reader_impl/testdata/provider_config.yml
diff --git a/protocol/rest/rest_interface/rest_config_reader.go b/config/rest/config_reader/rest_config_reader.go
similarity index 82%
rename from protocol/rest/rest_interface/rest_config_reader.go
rename to config/rest/config_reader/rest_config_reader.go
index d2222c260..366cde6a0 100644
--- a/protocol/rest/rest_interface/rest_config_reader.go
+++ b/config/rest/config_reader/rest_config_reader.go
@@ -15,9 +15,11 @@
  * limitations under the License.
  */
 
-package rest_interface
+package config_reader
+
+import "github.com/apache/dubbo-go/config/rest"
 
 type RestConfigReader interface {
-	ReadConsumerConfig() *RestConsumerConfig
-	ReadProviderConfig() *RestProviderConfig
+	ReadConsumerConfig() (*rest.RestConsumerConfig, error)
+	ReadProviderConfig() (*rest.RestProviderConfig, error)
 }
diff --git a/protocol/rest/rest_interface/rest_config.go b/config/rest/rest_config.go
similarity index 97%
rename from protocol/rest/rest_interface/rest_config.go
rename to config/rest/rest_config.go
index a7715cd09..7262776ec 100644
--- a/protocol/rest/rest_interface/rest_config.go
+++ b/config/rest/rest_config.go
@@ -15,10 +15,11 @@
  * limitations under the License.
  */
 
-package rest_interface
+package rest
 
 import "github.com/creasty/defaults"
 
+// RestConsumerConfig ...
 type RestConsumerConfig struct {
 	Client                string                        `default:"resty" yaml:"rest_client" json:"rest_client,omitempty" property:"rest_client"`
 	Produces              string                        `default:"application/json" yaml:"rest_produces"  json:"rest_produces,omitempty" property:"rest_produces"`
@@ -38,6 +39,7 @@ func (c *RestConsumerConfig) UnmarshalYAML(unmarshal func(interface{}) error) er
 	return nil
 }
 
+// RestProviderConfig ...
 type RestProviderConfig struct {
 	Server                string                        `default:"go-restful" yaml:"rest_server" json:"rest_server,omitempty" property:"rest_server"`
 	Produces              string                        `default:"*/*" yaml:"rest_produces"  json:"rest_produces,omitempty" property:"rest_produces"`
@@ -57,6 +59,7 @@ func (c *RestProviderConfig) UnmarshalYAML(unmarshal func(interface{}) error) er
 	return nil
 }
 
+// RestServiceConfig ...
 type RestServiceConfig struct {
 	InterfaceName        string              `required:"true"  yaml:"interface"  json:"interface,omitempty" property:"interface"`
 	Url                  string              `yaml:"url"  json:"url,omitempty" property:"url"`
@@ -82,6 +85,7 @@ func (c *RestServiceConfig) UnmarshalYAML(unmarshal func(interface{}) error) err
 	return nil
 }
 
+// RestMethodConfig ...
 type RestMethodConfig struct {
 	InterfaceName  string
 	MethodName     string `required:"true" yaml:"name"  json:"name,omitempty" property:"name"`
diff --git a/protocol/rest/rest_config_initializer.go b/config/rest_config_loader.go
similarity index 61%
rename from protocol/rest/rest_config_initializer.go
rename to config/rest_config_loader.go
index a80dce98b..1d8f5ac63 100644
--- a/protocol/rest/rest_config_initializer.go
+++ b/config/rest_config_loader.go
@@ -15,64 +15,85 @@
  * limitations under the License.
  */
 
-package rest
+package config
 
 import (
+	"log"
 	"strconv"
 	"strings"
 )
 
+import (
+	perrors "github.com/pkg/errors"
+)
+
 import (
 	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/common/extension"
 	"github.com/apache/dubbo-go/common/logger"
-	"github.com/apache/dubbo-go/config"
-	_ "github.com/apache/dubbo-go/protocol/rest/rest_config_reader"
-	"github.com/apache/dubbo-go/protocol/rest/rest_interface"
+	"github.com/apache/dubbo-go/config/rest"
+	_ "github.com/apache/dubbo-go/config/rest/config_reader/reader_impl"
 )
 
 var (
-	restConsumerServiceConfigMap map[string]*rest_interface.RestServiceConfig
-	restProviderServiceConfigMap map[string]*rest_interface.RestServiceConfig
+	restConsumerServiceConfigMap map[string]*rest.RestServiceConfig
+	restProviderServiceConfigMap map[string]*rest.RestServiceConfig
 )
 
 func init() {
-	initConsumerRestConfig()
-	initProviderRestConfig()
+	if err := initConsumerRestConfig(); err != nil {
+		log.Printf("[initConsumerRestConfig] %#v", err)
+	}
+	if err := initProviderRestConfig(); err != nil {
+		log.Printf("[initProviderRestConfig] %#v", err)
+	}
 }
 
-func initConsumerRestConfig() {
-	consumerConfigType := config.GetConsumerConfig().RestConfigType
+// initConsumerRestConfig ...
+func initConsumerRestConfig() error {
+	consumerConfigType := GetConsumerConfig().RestConfigType
 	consumerConfigReader := extension.GetSingletonRestConfigReader(consumerConfigType)
-	restConsumerConfig := consumerConfigReader.ReadConsumerConfig()
+	var restConsumerConfig *rest.RestConsumerConfig
+	var err error
+	if restConsumerConfig, err = consumerConfigReader.ReadConsumerConfig(); err != nil {
+		return err
+	}
 	if restConsumerConfig == nil || len(restConsumerConfig.RestServiceConfigsMap) == 0 {
-		return
+		return perrors.New("Consumer don't has RestServiceConfigsMap ")
 	}
-	restConsumerServiceConfigMap = make(map[string]*rest_interface.RestServiceConfig, len(restConsumerConfig.RestServiceConfigsMap))
+	restConsumerServiceConfigMap = make(map[string]*rest.RestServiceConfig, len(restConsumerConfig.RestServiceConfigsMap))
 	for key, rc := range restConsumerConfig.RestServiceConfigsMap {
 		rc.Client = getNotEmptyStr(rc.Client, restConsumerConfig.Client, constant.DEFAULT_REST_CLIENT)
 		rc.RestMethodConfigsMap = initMethodConfigMap(rc, restConsumerConfig.Consumes, restConsumerConfig.Produces)
 		restConsumerServiceConfigMap[strings.TrimPrefix(key, "/")] = rc
 	}
+	return nil
 }
 
-func initProviderRestConfig() {
-	providerConfigType := config.GetProviderConfig().RestConfigType
+// initProviderRestConfig ...
+func initProviderRestConfig() error {
+	providerConfigType := GetProviderConfig().RestConfigType
 	providerConfigReader := extension.GetSingletonRestConfigReader(providerConfigType)
-	restProviderConfig := providerConfigReader.ReadProviderConfig()
+	var restProviderConfig *rest.RestProviderConfig
+	var err error
+	if restProviderConfig, err = providerConfigReader.ReadProviderConfig(); err != nil {
+		return err
+	}
 	if restProviderConfig == nil || len(restProviderConfig.RestServiceConfigsMap) == 0 {
-		return
+		return perrors.New("Provider don't has RestServiceConfigsMap is nil")
 	}
-	restProviderServiceConfigMap = make(map[string]*rest_interface.RestServiceConfig, len(restProviderConfig.RestServiceConfigsMap))
+	restProviderServiceConfigMap = make(map[string]*rest.RestServiceConfig, len(restProviderConfig.RestServiceConfigsMap))
 	for key, rc := range restProviderConfig.RestServiceConfigsMap {
 		rc.Server = getNotEmptyStr(rc.Server, restProviderConfig.Server, constant.DEFAULT_REST_SERVER)
 		rc.RestMethodConfigsMap = initMethodConfigMap(rc, restProviderConfig.Consumes, restProviderConfig.Produces)
 		restProviderServiceConfigMap[strings.TrimPrefix(key, "/")] = rc
 	}
+	return nil
 }
 
-func initMethodConfigMap(rc *rest_interface.RestServiceConfig, consumes string, produces string) map[string]*rest_interface.RestMethodConfig {
-	mcm := make(map[string]*rest_interface.RestMethodConfig, len(rc.RestMethodConfigs))
+// initProviderRestConfig ...
+func initMethodConfigMap(rc *rest.RestServiceConfig, consumes string, produces string) map[string]*rest.RestMethodConfig {
+	mcm := make(map[string]*rest.RestMethodConfig, len(rc.RestMethodConfigs))
 	for _, mc := range rc.RestMethodConfigs {
 		mc.InterfaceName = rc.InterfaceName
 		mc.Path = rc.Path + mc.Path
@@ -85,6 +106,7 @@ func initMethodConfigMap(rc *rest_interface.RestServiceConfig, consumes string,
 	return mcm
 }
 
+// function will return first not empty string ..
 func getNotEmptyStr(args ...string) string {
 	var r string
 	for _, t := range args {
@@ -96,7 +118,8 @@ func getNotEmptyStr(args ...string) string {
 	return r
 }
 
-func transformMethodConfig(methodConfig *rest_interface.RestMethodConfig) *rest_interface.RestMethodConfig {
+// transformMethodConfig
+func transformMethodConfig(methodConfig *rest.RestMethodConfig) *rest.RestMethodConfig {
 	if len(methodConfig.PathParamsMap) == 0 && len(methodConfig.PathParams) > 0 {
 		paramsMap, err := parseParamsString2Map(methodConfig.PathParams)
 		if err != nil {
@@ -124,6 +147,9 @@ func transformMethodConfig(methodConfig *rest_interface.RestMethodConfig) *rest_
 	return methodConfig
 }
 
+// transform a string to a map
+// for example:
+// string "0:id,1:name" => map [0:id,1:name]
 func parseParamsString2Map(params string) (map[int]string, error) {
 	m := make(map[int]string, 8)
 	for _, p := range strings.Split(params, ",") {
@@ -137,18 +163,22 @@ func parseParamsString2Map(params string) (map[int]string, error) {
 	return m, nil
 }
 
-func GetRestConsumerServiceConfig(path string) *rest_interface.RestServiceConfig {
+// GetRestConsumerServiceConfig ...
+func GetRestConsumerServiceConfig(path string) *rest.RestServiceConfig {
 	return restConsumerServiceConfigMap[path]
 }
 
-func GetRestProviderServiceConfig(path string) *rest_interface.RestServiceConfig {
+// GetRestProviderServiceConfig ...
+func GetRestProviderServiceConfig(path string) *rest.RestServiceConfig {
 	return restProviderServiceConfigMap[path]
 }
 
-func SetRestConsumerServiceConfigMap(configMap map[string]*rest_interface.RestServiceConfig) {
+// SetRestConsumerServiceConfigMap ...
+func SetRestConsumerServiceConfigMap(configMap map[string]*rest.RestServiceConfig) {
 	restConsumerServiceConfigMap = configMap
 }
 
-func SetRestProviderServiceConfigMap(configMap map[string]*rest_interface.RestServiceConfig) {
+// SetRestProviderServiceConfigMap ...
+func SetRestProviderServiceConfigMap(configMap map[string]*rest.RestServiceConfig) {
 	restProviderServiceConfigMap = configMap
 }
diff --git a/protocol/rest/rest_config_initializer_test.go b/config/rest_config_loader_test.go
similarity index 88%
rename from protocol/rest/rest_config_initializer_test.go
rename to config/rest_config_loader_test.go
index 5def4d4df..50546ba84 100644
--- a/protocol/rest/rest_config_initializer_test.go
+++ b/config/rest_config_loader_test.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package rest
+package config
 
 import (
 	"os"
@@ -31,9 +31,10 @@ import (
 )
 
 func TestGetRestConsumerServiceConfig(t *testing.T) {
-	err := os.Setenv(constant.CONF_CONSUMER_FILE_PATH, "./rest_config_reader/testdata/consumer_config.yml")
+	err := os.Setenv(constant.CONF_CONSUMER_FILE_PATH, "./rest/config_reader/reader_impl/testdata/consumer_config.yml")
+	assert.NoError(t, err)
+	err = initConsumerRestConfig()
 	assert.NoError(t, err)
-	initConsumerRestConfig()
 	serviceConfig := GetRestConsumerServiceConfig("UserProvider")
 	assert.NotEmpty(t, serviceConfig)
 	assert.NotEmpty(t, serviceConfig.RestMethodConfigsMap)
@@ -48,9 +49,10 @@ func TestGetRestConsumerServiceConfig(t *testing.T) {
 }
 
 func TestGetRestProviderServiceConfig(t *testing.T) {
-	err := os.Setenv(constant.CONF_PROVIDER_FILE_PATH, "./rest_config_reader/testdata/provider_config.yml")
+	err := os.Setenv(constant.CONF_PROVIDER_FILE_PATH, "./rest/config_reader/reader_impl/testdata/provider_config.yml")
+	assert.NoError(t, err)
+	err = initProviderRestConfig()
 	assert.NoError(t, err)
-	initProviderRestConfig()
 	serviceConfig := GetRestProviderServiceConfig("UserProvider")
 	assert.NotEmpty(t, serviceConfig)
 	assert.NotEmpty(t, serviceConfig.RestMethodConfigsMap)
diff --git a/protocol/rest/rest_interface/rest_server.go b/protocol/rest/rest_interface/rest_server.go
index f0c9a5f31..825c818bf 100644
--- a/protocol/rest/rest_interface/rest_server.go
+++ b/protocol/rest/rest_interface/rest_server.go
@@ -19,12 +19,13 @@ package rest_interface
 
 import (
 	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/config/rest"
 	"github.com/apache/dubbo-go/protocol"
 )
 
 type RestServer interface {
 	Start(url common.URL)
-	Deploy(invoker protocol.Invoker, restMethodConfig map[string]*RestMethodConfig)
-	UnDeploy(restMethodConfig map[string]*RestMethodConfig)
+	Deploy(invoker protocol.Invoker, restMethodConfig map[string]*rest.RestMethodConfig)
+	UnDeploy(restMethodConfig map[string]*rest.RestMethodConfig)
 	Destroy()
 }
diff --git a/protocol/rest/rest_invoker.go b/protocol/rest/rest_invoker.go
index 446d122e6..724b21f76 100644
--- a/protocol/rest/rest_invoker.go
+++ b/protocol/rest/rest_invoker.go
@@ -28,6 +28,7 @@ import (
 
 import (
 	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/config/rest"
 	"github.com/apache/dubbo-go/protocol"
 	invocation_impl "github.com/apache/dubbo-go/protocol/invocation"
 	"github.com/apache/dubbo-go/protocol/rest/rest_interface"
@@ -36,10 +37,10 @@ import (
 type RestInvoker struct {
 	protocol.BaseInvoker
 	client              rest_interface.RestClient
-	restMethodConfigMap map[string]*rest_interface.RestMethodConfig
+	restMethodConfigMap map[string]*rest.RestMethodConfig
 }
 
-func NewRestInvoker(url common.URL, client *rest_interface.RestClient, restMethodConfig map[string]*rest_interface.RestMethodConfig) *RestInvoker {
+func NewRestInvoker(url common.URL, client *rest_interface.RestClient, restMethodConfig map[string]*rest.RestMethodConfig) *RestInvoker {
 	return &RestInvoker{
 		BaseInvoker:         *protocol.NewBaseInvoker(url),
 		client:              *client,
diff --git a/protocol/rest/rest_invoker_test.go b/protocol/rest/rest_invoker_test.go
index d6419a309..617bb6656 100644
--- a/protocol/rest/rest_invoker_test.go
+++ b/protocol/rest/rest_invoker_test.go
@@ -31,9 +31,10 @@ import (
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/extension"
 	"github.com/apache/dubbo-go/config"
+	"github.com/apache/dubbo-go/config/rest"
+	_ "github.com/apache/dubbo-go/config/rest/config_reader/reader_impl"
 	"github.com/apache/dubbo-go/protocol/invocation"
 	"github.com/apache/dubbo-go/protocol/rest/rest_client"
-	_ "github.com/apache/dubbo-go/protocol/rest/rest_config_reader"
 	"github.com/apache/dubbo-go/protocol/rest/rest_interface"
 )
 
@@ -51,8 +52,8 @@ func TestRestInvoker_Invoke(t *testing.T) {
 	assert.NoError(t, err)
 	con := config.ProviderConfig{}
 	config.SetProviderConfig(con)
-	configMap := make(map[string]*rest_interface.RestServiceConfig)
-	methodConfigMap := make(map[string]*rest_interface.RestMethodConfig)
+	configMap := make(map[string]*rest.RestServiceConfig)
+	methodConfigMap := make(map[string]*rest.RestMethodConfig)
 	queryParamsMap := make(map[int]string)
 	queryParamsMap[1] = "age"
 	queryParamsMap[2] = "name"
@@ -60,7 +61,7 @@ func TestRestInvoker_Invoke(t *testing.T) {
 	pathParamsMap[0] = "userid"
 	headersMap := make(map[int]string)
 	headersMap[3] = "Content-Type"
-	methodConfigMap["GetUserOne"] = &rest_interface.RestMethodConfig{
+	methodConfigMap["GetUserOne"] = &rest.RestMethodConfig{
 		InterfaceName:  "",
 		MethodName:     "GetUserOne",
 		Path:           "/GetUserOne",
@@ -73,7 +74,7 @@ func TestRestInvoker_Invoke(t *testing.T) {
 		QueryParamsMap: nil,
 		Body:           0,
 	}
-	methodConfigMap["GetUserTwo"] = &rest_interface.RestMethodConfig{
+	methodConfigMap["GetUserTwo"] = &rest.RestMethodConfig{
 		InterfaceName:  "",
 		MethodName:     "GetUserTwo",
 		Path:           "/GetUserTwo",
@@ -86,7 +87,7 @@ func TestRestInvoker_Invoke(t *testing.T) {
 		QueryParamsMap: nil,
 		Body:           0,
 	}
-	methodConfigMap["GetUserThree"] = &rest_interface.RestMethodConfig{
+	methodConfigMap["GetUserThree"] = &rest.RestMethodConfig{
 		InterfaceName:  "",
 		MethodName:     "GetUserThree",
 		Path:           "/GetUserThree",
@@ -99,7 +100,7 @@ func TestRestInvoker_Invoke(t *testing.T) {
 		QueryParamsMap: nil,
 		Body:           0,
 	}
-	methodConfigMap["GetUserFour"] = &rest_interface.RestMethodConfig{
+	methodConfigMap["GetUserFour"] = &rest.RestMethodConfig{
 		InterfaceName:  "",
 		MethodName:     "GetUserFour",
 		Path:           "/GetUserFour",
@@ -112,7 +113,7 @@ func TestRestInvoker_Invoke(t *testing.T) {
 		QueryParamsMap: nil,
 		Body:           0,
 	}
-	methodConfigMap["GetUserFive"] = &rest_interface.RestMethodConfig{
+	methodConfigMap["GetUserFive"] = &rest.RestMethodConfig{
 		InterfaceName: "",
 		MethodName:    "GetUserFive",
 		Path:          "/GetUserFive",
@@ -120,7 +121,7 @@ func TestRestInvoker_Invoke(t *testing.T) {
 		Consumes:      "*/*",
 		MethodType:    "GET",
 	}
-	methodConfigMap["GetUser"] = &rest_interface.RestMethodConfig{
+	methodConfigMap["GetUser"] = &rest.RestMethodConfig{
 		InterfaceName:  "",
 		MethodName:     "GetUser",
 		Path:           "/GetUser/{userid}",
@@ -135,16 +136,16 @@ func TestRestInvoker_Invoke(t *testing.T) {
 		HeadersMap:     headersMap,
 	}
 
-	configMap["com.ikurento.user.UserProvider"] = &rest_interface.RestServiceConfig{
+	configMap["com.ikurento.user.UserProvider"] = &rest.RestServiceConfig{
 		Server:               "go-restful",
 		RestMethodConfigsMap: methodConfigMap,
 	}
-	SetRestProviderServiceConfigMap(configMap)
+	config.SetRestProviderServiceConfigMap(configMap)
 	proxyFactory := extension.GetProxyFactory("default")
 	proto.Export(proxyFactory.GetInvoker(url))
 	time.Sleep(5 * time.Second)
-	configMap = make(map[string]*rest_interface.RestServiceConfig)
-	configMap["com.ikurento.user.UserProvider"] = &rest_interface.RestServiceConfig{
+	configMap = make(map[string]*rest.RestServiceConfig)
+	configMap["com.ikurento.user.UserProvider"] = &rest.RestServiceConfig{
 		RestMethodConfigsMap: methodConfigMap,
 	}
 	restClient := rest_client.GetRestyClient(&rest_interface.RestOptions{ConnectTimeout: 3 * time.Second, RequestTimeout: 3 * time.Second})
diff --git a/protocol/rest/rest_protocol.go b/protocol/rest/rest_protocol.go
index fe147e25a..d8e17d90b 100644
--- a/protocol/rest/rest_protocol.go
+++ b/protocol/rest/rest_protocol.go
@@ -64,7 +64,7 @@ func (rp *RestProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
 	url := invoker.GetUrl()
 	serviceKey := url.ServiceKey()
 	exporter := NewRestExporter(serviceKey, invoker, rp.ExporterMap())
-	restServiceConfig := GetRestProviderServiceConfig(strings.TrimPrefix(url.Path, "/"))
+	restServiceConfig := config.GetRestProviderServiceConfig(strings.TrimPrefix(url.Path, "/"))
 	if restServiceConfig == nil {
 		logger.Errorf("%s service doesn't has provider config", url.Path)
 		return nil
@@ -83,7 +83,7 @@ func (rp *RestProtocol) Refer(url common.URL) protocol.Invoker {
 	if t, err := time.ParseDuration(requestTimeoutStr); err == nil {
 		requestTimeout = t
 	}
-	restServiceConfig := GetRestConsumerServiceConfig(strings.TrimPrefix(url.Path, "/"))
+	restServiceConfig := config.GetRestConsumerServiceConfig(strings.TrimPrefix(url.Path, "/"))
 	if restServiceConfig == nil {
 		logger.Errorf("%s service doesn't has consumer config", url.Path)
 		return nil
@@ -107,11 +107,12 @@ func (rp *RestProtocol) getServer(url common.URL, serverType string) rest_interf
 	rp.serverLock.Lock()
 	defer rp.serverLock.Unlock()
 	restServer, ok = rp.serverMap[url.Location]
-	if !ok {
-		restServer = extension.GetNewRestServer(serverType)
-		restServer.Start(url)
-		rp.serverMap[url.Location] = restServer
+	if ok {
+		return restServer
 	}
+	restServer = extension.GetNewRestServer(serverType)
+	restServer.Start(url)
+	rp.serverMap[url.Location] = restServer
 	return restServer
 }
 
@@ -123,10 +124,11 @@ func (rp *RestProtocol) getClient(restOptions rest_interface.RestOptions, client
 	rp.clientLock.Lock()
 	defer rp.clientLock.Unlock()
 	restClient, ok = rp.clientMap[restOptions]
-	if !ok {
-		restClient = extension.GetNewRestClient(clientType, &restOptions)
-		rp.clientMap[restOptions] = restClient
+	if ok {
+		return restClient
 	}
+	restClient = extension.GetNewRestClient(clientType, &restOptions)
+	rp.clientMap[restOptions] = restClient
 	return restClient
 }
 
diff --git a/protocol/rest/rest_protocol_test.go b/protocol/rest/rest_protocol_test.go
index 8dde59c4e..30d41b352 100644
--- a/protocol/rest/rest_protocol_test.go
+++ b/protocol/rest/rest_protocol_test.go
@@ -35,7 +35,7 @@ import (
 	"github.com/apache/dubbo-go/common/extension"
 	_ "github.com/apache/dubbo-go/common/proxy/proxy_factory"
 	"github.com/apache/dubbo-go/config"
-	"github.com/apache/dubbo-go/protocol/rest/rest_interface"
+	"github.com/apache/dubbo-go/config/rest"
 )
 
 func TestRestProtocol_Refer(t *testing.T) {
@@ -52,11 +52,11 @@ func TestRestProtocol_Refer(t *testing.T) {
 		RequestTimeout: 5 * time.Second,
 	}
 	config.SetConsumerConfig(con)
-	configMap := make(map[string]*rest_interface.RestServiceConfig)
-	configMap["com.ikurento.user.UserProvider"] = &rest_interface.RestServiceConfig{
+	configMap := make(map[string]*rest.RestServiceConfig)
+	configMap["com.ikurento.user.UserProvider"] = &rest.RestServiceConfig{
 		Client: "resty",
 	}
-	SetRestConsumerServiceConfigMap(configMap)
+	config.SetRestConsumerServiceConfigMap(configMap)
 	invoker := proto.Refer(url)
 
 	// make sure url
@@ -84,14 +84,14 @@ func TestRestProtocol_Export(t *testing.T) {
 	assert.NoError(t, err)
 	con := config.ProviderConfig{}
 	config.SetProviderConfig(con)
-	configMap := make(map[string]*rest_interface.RestServiceConfig)
-	methodConfigMap := make(map[string]*rest_interface.RestMethodConfig)
+	configMap := make(map[string]*rest.RestServiceConfig)
+	methodConfigMap := make(map[string]*rest.RestMethodConfig)
 	queryParamsMap := make(map[int]string)
 	queryParamsMap[1] = "age"
 	queryParamsMap[2] = "name"
 	pathParamsMap := make(map[int]string)
 	pathParamsMap[0] = "userid"
-	methodConfigMap["GetUser"] = &rest_interface.RestMethodConfig{
+	methodConfigMap["GetUser"] = &rest.RestMethodConfig{
 		InterfaceName:  "",
 		MethodName:     "GetUser",
 		Path:           "/GetUser/{userid}",
@@ -104,11 +104,11 @@ func TestRestProtocol_Export(t *testing.T) {
 		QueryParamsMap: queryParamsMap,
 		Body:           -1,
 	}
-	configMap["com.ikurento.user.UserProvider"] = &rest_interface.RestServiceConfig{
+	configMap["com.ikurento.user.UserProvider"] = &rest.RestServiceConfig{
 		Server:               "go-restful",
 		RestMethodConfigsMap: methodConfigMap,
 	}
-	SetRestProviderServiceConfigMap(configMap)
+	config.SetRestProviderServiceConfigMap(configMap)
 	proxyFactory := extension.GetProxyFactory("default")
 	exporter := proto.Export(proxyFactory.GetInvoker(url))
 	// make sure url
diff --git a/protocol/rest/rest_server/go_restful_server.go b/protocol/rest/rest_server/go_restful_server.go
index f6a867d77..8a5b94265 100644
--- a/protocol/rest/rest_server/go_restful_server.go
+++ b/protocol/rest/rest_server/go_restful_server.go
@@ -29,6 +29,7 @@ import (
 )
 
 import (
+	"github.com/apache/dubbo-go/config/rest"
 	"github.com/emicklei/go-restful/v3"
 	perrors "github.com/pkg/errors"
 )
@@ -74,7 +75,7 @@ func (grs *GoRestfulServer) Start(url common.URL) {
 	}()
 }
 
-func (grs *GoRestfulServer) Deploy(invoker protocol.Invoker, restMethodConfig map[string]*rest_interface.RestMethodConfig) {
+func (grs *GoRestfulServer) Deploy(invoker protocol.Invoker, restMethodConfig map[string]*rest.RestMethodConfig) {
 	svc := common.ServiceMap.GetService(invoker.GetUrl().Protocol, strings.TrimPrefix(invoker.GetUrl().Path, "/"))
 	for methodName, config := range restMethodConfig {
 		// get method
@@ -92,7 +93,7 @@ func (grs *GoRestfulServer) Deploy(invoker protocol.Invoker, restMethodConfig ma
 }
 
 func getFunc(methodName string, invoker protocol.Invoker, argsTypes []reflect.Type,
-	replyType reflect.Type, config *rest_interface.RestMethodConfig) func(req *restful.Request, resp *restful.Response) {
+	replyType reflect.Type, config *rest.RestMethodConfig) func(req *restful.Request, resp *restful.Response) {
 	return func(req *restful.Request, resp *restful.Response) {
 		var (
 			err  error
@@ -118,7 +119,7 @@ func getFunc(methodName string, invoker protocol.Invoker, argsTypes []reflect.Ty
 		}
 	}
 }
-func (grs *GoRestfulServer) UnDeploy(restMethodConfig map[string]*rest_interface.RestMethodConfig) {
+func (grs *GoRestfulServer) UnDeploy(restMethodConfig map[string]*rest.RestMethodConfig) {
 	for _, config := range restMethodConfig {
 		ws := new(restful.WebService)
 		ws.Path(config.Path)
@@ -138,7 +139,7 @@ func (grs *GoRestfulServer) Destroy() {
 	logger.Infof("[Go Restful] Server exiting")
 }
 
-func getArgsInterfaceFromRequest(req *restful.Request, config *rest_interface.RestMethodConfig) []interface{} {
+func getArgsInterfaceFromRequest(req *restful.Request, config *rest.RestMethodConfig) []interface{} {
 	argsMap := make(map[int]interface{}, 8)
 	maxKey := 0
 	for k, v := range config.PathParamsMap {
@@ -185,7 +186,7 @@ func getArgsInterfaceFromRequest(req *restful.Request, config *rest_interface.Re
 	return args
 }
 
-func getArgsFromRequest(req *restful.Request, argsTypes []reflect.Type, config *rest_interface.RestMethodConfig) []interface{} {
+func getArgsFromRequest(req *restful.Request, argsTypes []reflect.Type, config *rest.RestMethodConfig) []interface{} {
 	argsLength := len(argsTypes)
 	args := make([]interface{}, argsLength)
 	for i, t := range argsTypes {
-- 
GitLab