diff --git a/service/rpc/builder.go b/service/rpc/builder.go index ab388e8c..b90f60ad 100644 --- a/service/rpc/builder.go +++ b/service/rpc/builder.go @@ -107,7 +107,11 @@ func (b *builder) AddDescriptor(descriptors ...interface{}) error { path = "/" } for _, action := range descriptor.Actions { - b.bindings[genRPCPath(path, action.Version, action.Name)] = &binding{ + rpcPath := genRPCPath(path, action.Version, action.Name) + if _, ok := b.bindings[rpcPath]; ok { + return fmt.Errorf("duplicated rpc path: %s", rpcPath) + } + b.bindings[rpcPath] = &binding{ middlewares: descriptor.Middlewares, definition: b.genDefinition(action, descriptor.Consumes, descriptor.Produces, descriptor.Tags), } diff --git a/service/rpc/builder_test.go b/service/rpc/builder_test.go index fbd90a88..bc3f42cc 100644 --- a/service/rpc/builder_test.go +++ b/service/rpc/builder_test.go @@ -303,6 +303,33 @@ func TestDefinitions(t *testing.T) { } } +func TestDuplicatedRPCPath(t *testing.T) { + const version = "2020-10-10" + action := definition.RPCAction{ + Name: "GetFoo", + Version: version, + Function: func() (string, error) { + return "", nil + }, + Results: definition.DataErrorResults(""), + } + desc := definition.RPCDescriptor{ + Path: "/", + Description: "Test", + Consumes: []string{definition.MIMEAll}, + Produces: []string{definition.MIMEAll}, + Actions: []definition.RPCAction{action, action}, + } + builder := NewBuilder() + err := builder.AddDescriptor(desc) + if err == nil { + t.Fatal("Unexpected success") + } + if !strings.Contains(err.Error(), "duplicated rpc path") { + t.Fatalf("Unexpected error: %v", err) + } +} + func BenchmarkServer(b *testing.B) { u, _ := url.Parse("/?Action=GetEcho&Version=2020-01-01&name=alice")