@@ -70,6 +70,42 @@ func validateReturns(handler reflect.Type) error {
70
70
return nil
71
71
}
72
72
73
+ // HandlerTrace allows handlers which wrap the return value of NewHandler to
74
+ // access to the request and response events.
75
+ type HandlerTrace struct {
76
+ RequestEvent func (context.Context , interface {})
77
+ ResponseEvent func (context.Context , interface {})
78
+ }
79
+
80
+ func callbackCompose (f1 , f2 func (context.Context , interface {})) func (context.Context , interface {}) {
81
+ return func (ctx context.Context , event interface {}) {
82
+ if nil != f1 {
83
+ f1 (ctx , event )
84
+ }
85
+ if nil != f2 {
86
+ f2 (ctx , event )
87
+ }
88
+ }
89
+ }
90
+
91
+ type handlerTraceKey struct {}
92
+
93
+ // WithHandlerTrace adds callbacks to the provided context which allows handlers
94
+ // which wrap the return value of NewHandler to access to the request and
95
+ // response events.
96
+ func WithHandlerTrace (ctx context.Context , trace HandlerTrace ) context.Context {
97
+ existing := contextHandlerTrace (ctx )
98
+ return context .WithValue (ctx , handlerTraceKey {}, HandlerTrace {
99
+ RequestEvent : callbackCompose (existing .RequestEvent , trace .RequestEvent ),
100
+ ResponseEvent : callbackCompose (existing .ResponseEvent , trace .ResponseEvent ),
101
+ })
102
+ }
103
+
104
+ func contextHandlerTrace (ctx context.Context ) HandlerTrace {
105
+ trace , _ := ctx .Value (handlerTraceKey {}).(HandlerTrace )
106
+ return trace
107
+ }
108
+
73
109
// NewHandler creates a base lambda handler from the given handler function. The
74
110
// returned Handler performs JSON deserialization and deserialization, and
75
111
// delegates to the input handler function. The handler function parameter must
@@ -95,6 +131,9 @@ func NewHandler(handlerFunc interface{}) Handler {
95
131
}
96
132
97
133
return lambdaHandler (func (ctx context.Context , payload []byte ) (interface {}, error ) {
134
+
135
+ trace := contextHandlerTrace (ctx )
136
+
98
137
// construct arguments
99
138
var args []reflect.Value
100
139
if takesContext {
@@ -107,7 +146,9 @@ func NewHandler(handlerFunc interface{}) Handler {
107
146
if err := json .Unmarshal (payload , event .Interface ()); err != nil {
108
147
return nil , err
109
148
}
110
-
149
+ if nil != trace .RequestEvent {
150
+ trace .RequestEvent (ctx , event .Elem ().Interface ())
151
+ }
111
152
args = append (args , event .Elem ())
112
153
}
113
154
@@ -123,6 +164,10 @@ func NewHandler(handlerFunc interface{}) Handler {
123
164
var val interface {}
124
165
if len (response ) > 1 {
125
166
val = response [0 ].Interface ()
167
+
168
+ if nil != trace .ResponseEvent {
169
+ trace .ResponseEvent (ctx , val )
170
+ }
126
171
}
127
172
128
173
return val , err
0 commit comments