SCB-1558 support query history by key and fix wrong API doc (#50)

diff --git a/client/adaptor/kie_client.go b/client/adaptor/kie_client.go
index f6a1f6b..c2d0137 100644
--- a/client/adaptor/kie_client.go
+++ b/client/adaptor/kie_client.go
@@ -98,7 +98,7 @@
 
 //PushConfigs put config in kie by key and labels.
 func (c *Client) PushConfigs(data map[string]interface{}, labels map[string]string) (map[string]interface{}, error) {
-	var configReq model.KVDoc
+	var configReq model.KVRequest
 	configResult := make(map[string]interface{})
 	for key, configValue := range data {
 		configReq.Key = key
diff --git a/client/client.go b/client/client.go
index 1190d6b..15a7163 100644
--- a/client/client.go
+++ b/client/client.go
@@ -84,7 +84,7 @@
 }
 
 //Put create value of a key
-func (c *Client) Put(ctx context.Context, kv model.KVDoc, opts ...OpOption) (*model.KVDoc, error) {
+func (c *Client) Put(ctx context.Context, kv model.KVRequest, opts ...OpOption) (*model.KVDoc, error) {
 	options := OpOptions{}
 	for _, o := range opts {
 		o(&options)
diff --git a/client/client_test.go b/client/client_test.go
index 0d1af45..eff33bb 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -77,7 +77,7 @@
 			c1, _ = New(Config{
 				Endpoint: "http://127.0.0.1:30110",
 			})
-			kv := model.KVDoc{
+			kv := model.KVRequest{
 				Key:    "app.properties",
 				Labels: map[string]string{"service": "tester"},
 				Value:  "1s",
@@ -106,11 +106,10 @@
 				Endpoint: "http://127.0.0.1:30110",
 			})
 
-			kvBody := model.KVDoc{}
+			kvBody := model.KVRequest{}
 			kvBody.Key = "time"
 			kvBody.Value = "100s"
 			kvBody.ValueType = "string"
-			kvBody.Project = "test"
 			kvBody.Labels = make(map[string]string)
 			kvBody.Labels["evn"] = "test"
 			kv, err := client2.Put(context.TODO(), kvBody, WithProject("test"))
diff --git a/cmd/kieserver/main.go b/cmd/kieserver/main.go
index cd397f9..e0b65fb 100644
--- a/cmd/kieserver/main.go
+++ b/cmd/kieserver/main.go
@@ -54,6 +54,24 @@
 			Destination: &Configs.ConfigFile,
 			Value:       defaultConfigFile,
 		},
+		cli.StringFlag{
+			Name:        "name",
+			Usage:       "node name, example: --name=kie0",
+			Destination: &Configs.ConfigFile,
+			EnvVar:      "NODE_NAME",
+		},
+		cli.StringFlag{
+			Name:        "peer-addr",
+			Usage:       "peer address any node address in a cluster, example: --peer-addr=10.1.1.10:5000",
+			Destination: &Configs.ConfigFile,
+			EnvVar:      "PEER_ADDR",
+		},
+		cli.StringFlag{
+			Name:        "listen-peer-addr",
+			Usage:       "peer address, example: --listen-peer-addr=0.0.0.0:5000",
+			Destination: &Configs.ConfigFile,
+			EnvVar:      "LISTEN_PEER_ADDR",
+		},
 	}
 	app.Action = func(c *cli.Context) error {
 		return nil
diff --git a/examples/dev/conf/lager.yaml b/examples/dev/conf/lager.yaml
index 419ae46..fcb45a1 100644
--- a/examples/dev/conf/lager.yaml
+++ b/examples/dev/conf/lager.yaml
@@ -1 +1 @@
-log_format_text: false
\ No newline at end of file
+log_level: DEBUG
\ No newline at end of file
diff --git a/examples/dev/conf/microservice.yaml b/examples/dev/conf/microservice.yaml
index 38aad04..0bd45c8 100755
--- a/examples/dev/conf/microservice.yaml
+++ b/examples/dev/conf/microservice.yaml
@@ -1,4 +1,4 @@
 ---
 service_description:
   name: servicecomb-kie
-  version: 0.0.1
+  version: 0.1.0
diff --git a/go.mod b/go.mod
index 32ee19d..edad9dc 100644
--- a/go.mod
+++ b/go.mod
@@ -1,10 +1,10 @@
 module github.com/apache/servicecomb-kie
 
 require (
-	github.com/emicklei/go-restful v2.8.0+incompatible
+	github.com/emicklei/go-restful v2.11.1+incompatible
 	github.com/go-chassis/foundation v0.0.0-20190621030543-c3b63f787f4c
 	github.com/go-chassis/go-archaius v0.24.0
-	github.com/go-chassis/go-chassis v1.7.3-0.20191018125535-1a99ab41f7ea
+	github.com/go-chassis/go-chassis v1.7.4-0.20191031115844-2d2fe55920d0
 	github.com/go-chassis/go-chassis-config v0.14.0
 	github.com/go-chassis/paas-lager v1.0.2-0.20190328010332-cf506050ddb2
 	github.com/go-mesh/openlogging v1.0.1
diff --git a/go.sum b/go.sum
index 302bd27..49ac2df 100644
--- a/go.sum
+++ b/go.sum
@@ -9,6 +9,8 @@
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/emicklei/go-restful v2.8.0+incompatible h1:wN8GCRDPGHguIynsnBartv5GUgGUg1LAU7+xnSn1j7Q=
 github.com/emicklei/go-restful v2.8.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/emicklei/go-restful v2.11.1+incompatible h1:CjKsv3uWcCMvySPQYKxO8XX3f9zD4FeZRsW4G0B4ffE=
+github.com/emicklei/go-restful v2.11.1+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/go-chassis/foundation v0.0.0-20190621030543-c3b63f787f4c h1:p+Y6yq7RwHmYjEr/vwdVYGacBqFCc2lPQfNRIC3vRIs=
@@ -17,10 +19,16 @@
 github.com/go-chassis/go-archaius v0.24.0/go.mod h1:5kKZrxGYvKNorKamngLdPe3vVasAtIeB5vDcAv8Vg9I=
 github.com/go-chassis/go-chassis v1.7.3-0.20191018125535-1a99ab41f7ea h1:Gm7df0N6uafuCCPvdMrihLvzKEu4Xl6yd2QYmqj2UG0=
 github.com/go-chassis/go-chassis v1.7.3-0.20191018125535-1a99ab41f7ea/go.mod h1:Zdiwu/crt8XWcwWJOu9MoE3Ld0KHJwSPtAkEHYlOErI=
+github.com/go-chassis/go-chassis v1.7.4-0.20191029093300-ce79305826f9 h1:IqUVYJ7/VNvIn+OzZ8+H1lCONQpFSBdZPBguBwanKso=
+github.com/go-chassis/go-chassis v1.7.4-0.20191029093300-ce79305826f9/go.mod h1:QJGDHyfKjt1gZjMXfdUbl+TJkOcdn7WuZpPjzRWbn+8=
+github.com/go-chassis/go-chassis v1.7.4-0.20191031115844-2d2fe55920d0 h1:jgfAkHzGcoq+6OOMihP4z0nFC76C0oWHwru2t2tHN9A=
+github.com/go-chassis/go-chassis v1.7.4-0.20191031115844-2d2fe55920d0/go.mod h1:QJGDHyfKjt1gZjMXfdUbl+TJkOcdn7WuZpPjzRWbn+8=
 github.com/go-chassis/go-chassis-config v0.14.0 h1:OnM9sx2GalDC7vEIhPecRpQlVa8hz10NOB41+9tii5A=
 github.com/go-chassis/go-chassis-config v0.14.0/go.mod h1:qzvK/aoAv0O/khmF6ehW6RgELrF1JR2F555T9izoo2A=
 github.com/go-chassis/go-restful-swagger20 v1.0.1 h1:HdGto0xroWGK504XN0Um7JBc0OPMHDlWwedkd2mTGII=
 github.com/go-chassis/go-restful-swagger20 v1.0.1/go.mod h1:s+06mcAnGsVYQ2sqM4ZPiMJeRj7BTeAM/4gkhZNcsjA=
+github.com/go-chassis/go-restful-swagger20 v1.0.2-0.20191029071646-8c0119f661c5 h1:jlUonIaxwdVZrP27t2mPKHDuBz913nXznn4dOtvHzPg=
+github.com/go-chassis/go-restful-swagger20 v1.0.2-0.20191029071646-8c0119f661c5/go.mod h1:s+06mcAnGsVYQ2sqM4ZPiMJeRj7BTeAM/4gkhZNcsjA=
 github.com/go-chassis/paas-lager v1.0.2-0.20190328010332-cf506050ddb2 h1:iORWPbIQ81tJPKWs9TNvcjCQnqvyTlL41F9ILgiTcyM=
 github.com/go-chassis/paas-lager v1.0.2-0.20190328010332-cf506050ddb2/go.mod h1:tILYbn3+0jjCxhY6/ue9L8eRq+VJ60U6VYIdugqchB4=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
diff --git a/pkg/model/kv.go b/pkg/model/kv.go
index 968574c..229ba7f 100644
--- a/pkg/model/kv.go
+++ b/pkg/model/kv.go
@@ -17,6 +17,15 @@
 
 package model
 
+//KVRequest is http request body
+type KVRequest struct {
+	Key       string            `json:"key" yaml:"key"`
+	Value     string            `json:"value,omitempty" yaml:"value,omitempty"`
+	ValueType string            `json:"value_type,omitempty" bson:"value_type,omitempty" yaml:"value_type,omitempty"` //ini,json,text,yaml,properties
+	Checker   string            `json:"check,omitempty" yaml:"check,omitempty"`                                       //python script
+	Labels    map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`                                     //redundant
+}
+
 //KVResponse represents the key value list
 type KVResponse struct {
 	LabelDoc *LabelDocResponse `json:"label"`
diff --git a/pkg/model/mongodb_doc.go b/pkg/model/mongodb_doc.go
index 2e18966..d60f3bb 100644
--- a/pkg/model/mongodb_doc.go
+++ b/pkg/model/mongodb_doc.go
@@ -51,6 +51,6 @@
 	LabelID  string            `json:"label_id,omitempty"  bson:"label_id,omitempty" yaml:"label_id,omitempty"`
 	Labels   map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
 	Domain   string            `json:"-" yaml:"-"`
-	KVs      []*KVDoc          `json:"data,omitempty" yaml:"data,omitempty"`
+	KVs      []*KVDoc          `json:"data,omitempty" bson:"data,omitempty" yaml:"data,omitempty"`
 	Revision int               `json:"revision" yaml:"revision"`
 }
diff --git a/server/resource/v1/doc_struct.go b/server/resource/v1/doc_struct.go
index d0d56a3..2870376 100644
--- a/server/resource/v1/doc_struct.go
+++ b/server/resource/v1/doc_struct.go
@@ -24,7 +24,7 @@
 	"github.com/go-chassis/go-chassis/server/restful"
 )
 
-//swagger doc elements
+//swagger doc header params
 var (
 	DocHeaderDepth = &restful.Parameters{
 		DataType:  "string",
@@ -32,14 +32,45 @@
 		ParamType: goRestful.HeaderParameterKind,
 		Desc:      "integer, default is 1, if you set match policy, you can set,depth to decide label number",
 	}
+)
+
+//swagger doc query params
+var (
 	DocQueryCombination = &restful.Parameters{
 		DataType:  "string",
 		Name:      common.QueryParamQ,
 		ParamType: goRestful.QueryParameterKind,
 		Desc: "the combination format is {label_key}:{label_value}+{label_key}:{label_value} " +
-			"for example: /v1/test/kie/kv?q=app:mall&q=app:mall+service:cart " +
+			"for example: /v1/test/kie/kv?q=app:mall&q=app:mall+service:cart, " +
 			"that will query key values from 2 kinds of labels",
 	}
+	DocQueryKVIDParameters = &restful.Parameters{
+		DataType:  "string",
+		Name:      "kvID",
+		ParamType: goRestful.QueryParameterKind,
+		Required:  true,
+	}
+	DocQueryKeyParameters = &restful.Parameters{
+		DataType:  "string",
+		Name:      "key",
+		ParamType: goRestful.QueryParameterKind,
+		Desc:      "only return history about a specific key",
+	}
+	DocQueryLabelParameters = &restful.Parameters{
+		DataType:  "string",
+		Name:      "any",
+		ParamType: goRestful.QueryParameterKind,
+		Desc:      "label pairs",
+	}
+	DocQueryLabelIDParameters = &restful.Parameters{
+		DataType:  "string",
+		Name:      "labelID",
+		ParamType: goRestful.QueryParameterKind,
+	}
+)
+
+//swagger doc path params
+var (
 	DocPathKey = &restful.Parameters{
 		DataType:  "string",
 		Name:      "key",
@@ -55,16 +86,6 @@
 		Name:      "label_id",
 		ParamType: goRestful.PathParameterKind,
 	}
-	kvIDParameters = &restful.Parameters{
-		DataType:  "string",
-		Name:      "kvID",
-		ParamType: goRestful.QueryParameterKind,
-	}
-	labelIDParameters = &restful.Parameters{
-		DataType:  "string",
-		Name:      "labelID",
-		ParamType: goRestful.QueryParameterKind,
-	}
 )
 
 //KVBody is open api doc
diff --git a/server/resource/v1/history_resource.go b/server/resource/v1/history_resource.go
index 210b72c..5f408a2 100644
--- a/server/resource/v1/history_resource.go
+++ b/server/resource/v1/history_resource.go
@@ -33,8 +33,8 @@
 type HistoryResource struct {
 }
 
-//GetRevisionsByLabelID search key only by label
-func (r *HistoryResource) GetRevisionsByLabelID(context *restful.Context) {
+//GetRevisions search key only by label
+func (r *HistoryResource) GetRevisions(context *restful.Context) {
 	var err error
 	labelID := context.ReadPathParameter("label_id")
 	if labelID == "" {
@@ -42,7 +42,8 @@
 		WriteErrResponse(context, http.StatusForbidden, "label_id must not be empty", common.ContentTypeText)
 		return
 	}
-	revisions, err := service.HistoryService.GetHistoryByLabelID(context.Ctx, labelID)
+	key := context.ReadQueryParameter("key")
+	revisions, err := service.HistoryService.GetHistory(context.Ctx, labelID, service.WithKey(key))
 	if err != nil {
 		if err == service.ErrRevisionNotExist {
 			WriteErrResponse(context, http.StatusNotFound, err.Error(), common.ContentTypeText)
@@ -65,12 +66,12 @@
 func (r *HistoryResource) URLPatterns() []restful.Route {
 	return []restful.Route{
 		{
-			Method:           http.MethodGet,
-			Path:             "/v1/{project}/kie/revision/{label_id}",
-			ResourceFuncName: "GetRevisionsByLabelID",
-			FuncDesc:         "get all revisions by label id",
+			Method:       http.MethodGet,
+			Path:         "/v1/{project}/kie/revision/{label_id}",
+			ResourceFunc: r.GetRevisions,
+			FuncDesc:     "get all revisions by label id",
 			Parameters: []*restful.Parameters{
-				DocPathProject, DocPathLabelID,
+				DocPathProject, DocPathLabelID, DocQueryKeyParameters,
 			},
 			Returns: []*restful.Returns{
 				{
diff --git a/server/resource/v1/kv_resource.go b/server/resource/v1/kv_resource.go
index 92cad46..ee0db4a 100644
--- a/server/resource/v1/kv_resource.go
+++ b/server/resource/v1/kv_resource.go
@@ -202,18 +202,14 @@
 func (r *KVResource) URLPatterns() []restful.Route {
 	return []restful.Route{
 		{
-			Method:           http.MethodPut,
-			Path:             "/v1/{project}/kie/kv/{key}",
-			ResourceFuncName: "Put",
-			FuncDesc:         "create or update key value",
+			Method:       http.MethodPut,
+			Path:         "/v1/{project}/kie/kv/{key}",
+			ResourceFunc: r.Put,
+			FuncDesc:     "create or update key value",
 			Parameters: []*restful.Parameters{
-				DocPathProject, DocPathKey, {
-					DataType:  "string",
-					Name:      "X-Realm",
-					ParamType: goRestful.HeaderParameterKind,
-					Desc:      "set kv to heterogeneous config server, not implement yet",
-				},
+				DocPathProject, DocPathKey,
 			},
+			Read: KVBody{},
 			Returns: []*restful.Returns{
 				{
 					Code:    http.StatusOK,
@@ -222,14 +218,15 @@
 			},
 			Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
 			Produces: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
-			Read:     KVBody{},
 		}, {
-			Method:           http.MethodGet,
-			Path:             "/v1/{project}/kie/kv/{key}",
-			ResourceFuncName: "GetByKey",
-			FuncDesc:         "get key values by key and labels",
+			Method:       http.MethodGet,
+			Path:         "/v1/{project}/kie/kv/{key}",
+			ResourceFunc: r.GetByKey,
+			FuncDesc:     "get key values by key and labels",
 			Parameters: []*restful.Parameters{
-				DocPathProject, DocPathKey, DocHeaderDepth,
+				DocPathProject, DocPathKey,
+				DocHeaderDepth,
+				DocQueryLabelParameters,
 			},
 			Returns: []*restful.Returns{
 				{
@@ -241,10 +238,10 @@
 			Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
 			Produces: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
 		}, {
-			Method:           http.MethodGet,
-			Path:             "/v1/{project}/kie/kv",
-			ResourceFuncName: "SearchByLabels",
-			FuncDesc:         "search key values by labels combination",
+			Method:       http.MethodGet,
+			Path:         "/v1/{project}/kie/kv",
+			ResourceFunc: r.SearchByLabels,
+			FuncDesc:     "search key values by labels combination",
 			Parameters: []*restful.Parameters{
 				DocPathProject, DocQueryCombination,
 			},
@@ -258,15 +255,14 @@
 			Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
 			Produces: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
 		}, {
-			Method:           http.MethodDelete,
-			Path:             "/v1/{project}/kie/kv/",
-			ResourceFuncName: "Delete",
-			FuncDesc: "Delete key by kvID and labelID,If the labelID is nil, query the collection kv to get it." +
-				"It means if only get kvID, it can also delete normally.But if you want better performance, you need to pass the labelID",
+			Method:       http.MethodDelete,
+			Path:         "/v1/{project}/kie/kv",
+			ResourceFunc: r.Delete,
+			FuncDesc:     "delete key by kvID and labelID. if you want better performance, you need to give labelID",
 			Parameters: []*restful.Parameters{
 				DocPathProject,
-				kvIDParameters,
-				labelIDParameters,
+				DocQueryKVIDParameters,
+				DocQueryLabelIDParameters,
 			},
 			Returns: []*restful.Returns{
 				{
diff --git a/server/service/mongo/history/dao.go b/server/service/mongo/history/dao.go
index bd5db63..8533ec0 100644
--- a/server/service/mongo/history/dao.go
+++ b/server/service/mongo/history/dao.go
@@ -71,7 +71,7 @@
 	if err != nil {
 		return nil, err
 	}
-	rvs := []*model.LabelRevisionDoc{}
+	rvs := make([]*model.LabelRevisionDoc, 0)
 	var exist bool
 	for cur.Next(ctx) {
 		var elem model.LabelRevisionDoc
@@ -81,7 +81,6 @@
 			return nil, err
 		}
 		exist = true
-		clearRevisionKV(&elem)
 		rvs = append(rvs, &elem)
 	}
 	if !exist {
diff --git a/server/service/mongo/history/service.go b/server/service/mongo/history/service.go
index d99c8af..85f7bdb 100644
--- a/server/service/mongo/history/service.go
+++ b/server/service/mongo/history/service.go
@@ -20,15 +20,30 @@
 import (
 	"context"
 	"github.com/apache/servicecomb-kie/pkg/model"
+	"github.com/apache/servicecomb-kie/server/service"
 	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/bson/primitive"
 )
 
 //Service is the implementation
 type Service struct {
 }
 
-//GetHistoryByLabelID get all history by label id
-func (s *Service) GetHistoryByLabelID(ctx context.Context, labelID string) ([]*model.LabelRevisionDoc, error) {
-	filter := bson.M{"label_id": labelID}
+//GetHistory get all history by label id
+func (s *Service) GetHistory(ctx context.Context, labelID string, options ...service.FindOption) ([]*model.LabelRevisionDoc, error) {
+	var filter primitive.M
+	opts := service.FindOptions{}
+	for _, o := range options {
+		o(&opts)
+	}
+	if opts.Key != "" {
+		filter = bson.M{
+			"label_id": labelID,
+			"data.key": opts.Key,
+		}
+
+	} else {
+		filter = bson.M{"label_id": labelID}
+	}
 	return getHistoryByLabelID(ctx, filter)
 }
diff --git a/server/service/mongo/history/service_test.go b/server/service/mongo/history/service_test.go
new file mode 100644
index 0000000..7cb0cb3
--- /dev/null
+++ b/server/service/mongo/history/service_test.go
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package history_test
+
+import (
+	"context"
+	"github.com/apache/servicecomb-kie/server/config"
+	"github.com/apache/servicecomb-kie/server/service/mongo/session"
+	"github.com/stretchr/testify/assert"
+	"go.mongodb.org/mongo-driver/bson"
+	"testing"
+)
+
+func init() {
+	config.Configurations = &config.Config{DB: config.DB{URI: "mongodb://kie:123@127.0.0.1:27017"}}
+	_ = session.Init()
+}
+
+func TestAddHistory(t *testing.T) {
+	ctx := context.Background()
+	coll := session.GetDB().Collection("label_revision")
+	cur, err := coll.Find(
+		context.Background(),
+		bson.M{
+			"label_id": "5dbc079183ff1a09242376e7",
+			"data.key": "lb",
+		})
+	assert.NoError(t, err)
+	for cur.Next(ctx) {
+		var elem interface{}
+		err := cur.Decode(&elem)
+		assert.NoError(t, err)
+		t.Log(elem)
+	}
+}
diff --git a/server/service/mongo/kv/kv_dao.go b/server/service/mongo/kv/kv_dao.go
index c5f534c..526efc2 100644
--- a/server/service/mongo/kv/kv_dao.go
+++ b/server/service/mongo/kv/kv_dao.go
@@ -184,9 +184,8 @@
 		return nil, err
 	}
 	kvs := make([]*model.KVDoc, 0)
-	curKV := &model.KVDoc{} //reduce GC,but need to clear labels
 	for cur.Next(ctx) {
-		curKV.Labels = nil
+		curKV := &model.KVDoc{}
 		if err := cur.Decode(curKV); err != nil {
 			openlogging.Error("decode to KVs error: " + err.Error())
 			return nil, err
@@ -207,7 +206,6 @@
 //key can be empty, then it will return all key values
 //if key is given, will return 0-1 key value
 func findKVByLabelID(ctx context.Context, domain, labelID, key string, project string) ([]*model.KVDoc, error) {
-
 	filter := bson.M{"label_id": labelID, "domain": domain, "project": project}
 	if key != "" {
 		filter["key"] = key
diff --git a/server/service/mongo/kv/kv_service.go b/server/service/mongo/kv/kv_service.go
index 30477c3..e93eaa8 100644
--- a/server/service/mongo/kv/kv_service.go
+++ b/server/service/mongo/kv/kv_service.go
@@ -55,12 +55,11 @@
 		}
 	}
 
-	//check whether the projecr has certain labels or not
+	//check whether the project has certain labels or not
 	labelID, err := label.Exist(ctx, kv.Domain, kv.Project, kv.Labels)
-
-	var l *model.LabelDoc
 	if err != nil {
 		if err == session.ErrLabelNotExists {
+			var l *model.LabelDoc
 			l, err = label.CreateLabel(ctx, kv.Domain, kv.Labels, kv.Project)
 			if err != nil {
 				openlogging.Error("create label failed", openlogging.WithTags(openlogging.Tags{
@@ -73,7 +72,6 @@
 		} else {
 			return nil, err
 		}
-
 	}
 	kv.LabelID = string(labelID)
 	if kv.ValueType == "" {
diff --git a/server/service/service.go b/server/service/service.go
index cd46d8b..04310f6 100644
--- a/server/service/service.go
+++ b/server/service/service.go
@@ -45,7 +45,7 @@
 
 //History provide api of History entity
 type History interface {
-	GetHistoryByLabelID(ctx context.Context, labelID string) ([]*model.LabelRevisionDoc, error)
+	GetHistory(ctx context.Context, labelID string, options ...FindOption) ([]*model.LabelRevisionDoc, error)
 }
 
 //Init init db session