From 49d0b15557e13ff1c49cb11c8f704dbfb984c526 Mon Sep 17 00:00:00 2001 From: Eeren Wong Date: Mon, 24 Feb 2020 14:04:30 +0800 Subject: [PATCH 1/7] go mod --- go.mod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.mod b/go.mod index adc732b..7dac6e3 100644 --- a/go.mod +++ b/go.mod @@ -14,3 +14,5 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.2.1 // indirect ) + +go 1.13 From be66ca345145f7584278234fd9f7f2fd4069ee0e Mon Sep 17 00:00:00 2001 From: Eeren Wong Date: Mon, 24 Feb 2020 14:05:03 +0800 Subject: [PATCH 2/7] context data add identity --- invocation.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/invocation.go b/invocation.go index 6574cfb..0e15c94 100644 --- a/invocation.go +++ b/invocation.go @@ -4,8 +4,9 @@ import "encoding/json" // ContextData data received from AppSync type ContextData struct { - Arguments json.RawMessage `json:"arguments"` - Source json.RawMessage `json:"source"` + Arguments json.RawMessage `json:"arguments"` + Source json.RawMessage `json:"source"` + Identity *json.RawMessage `json:"identity"` } // Invocation data received from AppSync @@ -25,3 +26,7 @@ func (in Invocation) payload() json.RawMessage { return in.Context.Source } + +func (in Invocation) identity() *json.RawMessage { + return in.Context.Identity +} From ac942fe5eb07c067abc2c16668c5ea699c723e6d Mon Sep 17 00:00:00 2001 From: Eeren Wong Date: Mon, 24 Feb 2020 14:06:28 +0800 Subject: [PATCH 3/7] resolver able to receive identity from payload --- repository_test.go | 40 +++++++++++++++++++++++++++++++++++++++- resolver.go | 21 +++++++++++++++++---- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/repository_test.go b/repository_test.go index 3ca3ac6..7128bdd 100644 --- a/repository_test.go +++ b/repository_test.go @@ -12,13 +12,17 @@ var _ = Describe("Repository", func() { type arguments struct { Bar string `json:"bar"` } + type identity struct { + Bar string `json:"bar"` + } type response struct { Foo string } r := New() r.Add("example.resolver", func(arg arguments) (response, error) { return response{"bar"}, nil }) r.Add("example.resolver.with.error", func(arg arguments) (response, error) { return response{"bar"}, errors.New("Has Error") }) - + r.Add("example.resolver.with.identity", func(arg arguments, ident identity) (response, error) { return response{"foo"}, nil }) + r.Add("example.resolver.with.identity.with.error", func(arg arguments, ident identity) (response, error) { return response{"foo"}, errors.New("Has Error") }) Context("Matching invocation", func() { res, err := r.Handle(Invocation{ Resolve: "example.resolver", @@ -36,6 +40,25 @@ var _ = Describe("Repository", func() { }) }) + Context("Matching invocation with identity", func() { + identityMessage := json.RawMessage(`{"bar":"foo"}`) + res, err := r.Handle(Invocation{ + Resolve: "example.resolver.with.identity", + Context: ContextData{ + Arguments: json.RawMessage(`{"bar":"foo"}`), + Identity: &identityMessage, + }, + }) + + It("Should not error", func() { + Expect(err).ToNot(HaveOccurred()) + }) + + It("Should have data", func() { + Expect(res.(response).Foo).To(Equal("foo")) + }) + }) + Context("Matching invocation with error", func() { _, err := r.Handle(Invocation{ Resolve: "example.resolver.with.error", @@ -49,6 +72,21 @@ var _ = Describe("Repository", func() { }) }) + Context("Matching invocation with identity and error", func() { + identityMessage := json.RawMessage(`{"bar:foo"}`) + _, err := r.Handle(Invocation{ + Resolve: "example.resolver.with.identity.with.error", + Context: ContextData{ + Arguments: json.RawMessage(`{"bar":"foo"}`), + Identity: &identityMessage, + }, + }) + + It("Should error", func() { + Expect(err).To(HaveOccurred()) + }) + }) + Context("Matching invocation with invalid payload", func() { _, err := r.Handle(Invocation{ Resolve: "example.resolver.with.error", diff --git a/resolver.go b/resolver.go index 440c849..b68cabe 100644 --- a/resolver.go +++ b/resolver.go @@ -10,20 +10,33 @@ type resolver struct { } func (r *resolver) hasArguments() bool { - return reflect.TypeOf(r.function).NumIn() == 1 + return reflect.TypeOf(r.function).NumIn() >= 1 +} +func (r *resolver) hasIdentity() bool { + return reflect.TypeOf(r.function).NumIn() >= 2 } -func (r *resolver) call(p json.RawMessage) (interface{}, error) { +func (r *resolver) call(p json.RawMessage, i *json.RawMessage) (interface{}, error) { var args []reflect.Value - var err error if r.hasArguments() { pld := payload{p} - args, err = pld.parse(reflect.TypeOf(r.function).In(0)) + arguments, err := pld.parse(reflect.TypeOf(r.function).In(0)) + + if err != nil { + return nil, err + } + args = append(args, *arguments) + } + + if r.hasIdentity() && i != nil { + idt := payload{*i} + identity, err := idt.parse(reflect.TypeOf(r.function).In(1)) if err != nil { return nil, err } + args = append(args, *identity) } returnValues := reflect.ValueOf(r.function).Call(args) From f570e50f24abdb0068aa2514cf228c65a005ad7d Mon Sep 17 00:00:00 2001 From: Eeren Wong Date: Mon, 24 Feb 2020 14:07:23 +0800 Subject: [PATCH 4/7] payload parse to pointer reflect value --- payload.go | 5 +++-- payload_test.go | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/payload.go b/payload.go index cd8049e..399bb78 100644 --- a/payload.go +++ b/payload.go @@ -10,12 +10,13 @@ type payload struct { Message json.RawMessage } -func (p payload) parse(argsType reflect.Type) ([]reflect.Value, error) { +func (p payload) parse(argsType reflect.Type) (*reflect.Value, error) { args := reflect.New(argsType) if err := json.Unmarshal(p.Message, args.Interface()); err != nil { return nil, fmt.Errorf("Unable to prepare payload: %s", err.Error()) } - return append([]reflect.Value{}, args.Elem()), nil + e := args.Elem() + return &e, nil } diff --git a/payload_test.go b/payload_test.go index 7972e5f..56daa94 100644 --- a/payload_test.go +++ b/payload_test.go @@ -42,13 +42,12 @@ var _ = Describe("Payload", func() { Expect(err).NotTo(HaveOccurred()) }) - It("should return struct", func() { + It("should return data", func() { Expect(args).NotTo(BeNil()) }) It("should parse data", func() { - Expect(args).To(HaveLen(1)) - Expect(args[0].FieldByName("Name").String()).To(Equal("example")) + Expect(args.FieldByName("Name").String()).To(Equal("example")) }) }) }) From 853a669567e09ab77fce5717d272b916619bbd31 Mon Sep 17 00:00:00 2001 From: Eeren Wong Date: Mon, 24 Feb 2020 14:07:52 +0800 Subject: [PATCH 5/7] resolver validate not more than 2 argument --- validate.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/validate.go b/validate.go index b866e47..c223516 100644 --- a/validate.go +++ b/validate.go @@ -28,8 +28,8 @@ var validators = validateList{ return nil }, func(h reflect.Type) error { - if num := h.NumIn(); num > 1 { - return fmt.Errorf("Resolver must not have more than one argument, got %v", num) + if num := h.NumIn(); num > 2 { + return fmt.Errorf("Resolver must not have more than two argument, got %v", num) } return nil From 6a3f292227ba0e88a58e1474752441f9ba543ffb Mon Sep 17 00:00:00 2001 From: Eeren Wong Date: Mon, 24 Feb 2020 14:08:11 +0800 Subject: [PATCH 6/7] resolver test too many parameters --- resolver_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resolver_test.go b/resolver_test.go index 5d54692..64e4af4 100644 --- a/resolver_test.go +++ b/resolver_test.go @@ -22,8 +22,7 @@ var _ = Describe("Resolver", func() { Entry("Not a function, but string", "123", "Resolver is not a function, got string"), Entry("Parameter is string", func(args string) (interface{}, error) { return nil, nil }, "Resolver argument must be struct"), - Entry("Too many parameters", func(args struct{}, foo struct{}) (interface{}, error) { return nil, nil }, "Resolver must not have more than one argument, got 2"), - + Entry("Too many parameters", func(args struct{}, identity struct{}, foo struct{}) (interface{}, error) { return nil, nil }, "Resolver must not have more than two argument, got 3"), Entry("No return value", func() {}, "Resolver must have at least one return value"), Entry("Non-error return value", func(args struct{}) interface{} { return nil }, "Last return value must be an error"), Entry("Multiple non-error return values", func(args struct{}) (interface{}, interface{}) { return nil, nil }, "Last return value must be an error"), From dd1d899aca7e5c2a801879ada78ac59add15177d Mon Sep 17 00:00:00 2001 From: Eeren Wong Date: Mon, 24 Feb 2020 14:11:53 +0800 Subject: [PATCH 7/7] dispatch payload with identity --- dispatch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dispatch.go b/dispatch.go index 9973eed..9b15397 100644 --- a/dispatch.go +++ b/dispatch.go @@ -10,7 +10,7 @@ func (d dispatch) Serve(in Invocation) (interface{}, error) { handler, found := d.repository.resolvers[in.Resolve] if found { - return handler.call(in.payload()) + return handler.call(in.payload(), in.identity()) } return nil, fmt.Errorf("No resolver found: %s", in.Resolve)