Skip to content

Commit c37df95

Browse files
Updated README
1 parent 08fab63 commit c37df95

File tree

6 files changed

+91
-29
lines changed

6 files changed

+91
-29
lines changed

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,61 @@
1111
[6]: https://goreportcard.com/report/github.com/cloudshiftinc/aws-lambda-demux
1212
[7]: https://codecov.io/gh/cloudshiftinc/aws-lambda-demux/branch/main/graph/badge.svg
1313
[8]: https://codecov.io/gh/cloudshiftinc/aws-lambda-demux
14+
15+
Library to help Go developers handle multiple types of events (de-multiplexing) in AWS Lambda functions.
16+
17+
# Getting Started
18+
19+
The primary function of this library is to create events of a specific type and dispatch those to appropriate handlers.
20+
21+
To do so the demuxxer is configured with `Factory` and `Handler` instances.
22+
23+
Factories are responsible for determining the type of the event (based off the incoming JSON) and creating an instance of that event.
24+
25+
Handlers are responsible for, well, handling that event. Handlers are as used in [aws-lambda-go ](https://github.com/aws/aws-lambda-go), with the restriction
26+
of having a signature of `func(context.Context, *eventType) (*responseType, error)`.
27+
28+
A minimal usage showing a lambda that handles REST API request and Websocket lifecycle events:
29+
30+
```go
31+
// main.go
32+
package main
33+
34+
import (
35+
"github.com/aws/aws-lambda-go/lambda"
36+
"github.com/cloudshiftinc/aws-lambda-demux"
37+
)
38+
39+
func main() {
40+
41+
cfg := &demux.Cfg{
42+
Factories: []demux.Factory{
43+
func(ctx *demux.EventContext) any {
44+
if demux.HasAttribute(ctx.event, "connectionId") {
45+
return &events.APIGatewayWebsocketProxyRequest{}
46+
}
47+
return &events.APIGatewayProxyRequest{}
48+
},
49+
},
50+
Handlers: []any{
51+
func(ctx context.Context, event *events.APIGatewayWebsocketProxyRequest) (
52+
*events.APIGatewayProxyResponse, error) {
53+
// TODO - your code here to handle websocket event
54+
return &events.APIGatewayProxyResponse{}, nil
55+
},
56+
func(ctx context.Context, event *events.APIGatewayProxyRequest) (
57+
*events.APIGatewayProxyResponse,
58+
error) {
59+
// TODO - your code here to handle HTTP/REST event
60+
return &events.APIGatewayProxyResponse{}, nil
61+
},
62+
},
63+
}
64+
65+
lambda.Start(demux.NewHandler(cfg))
66+
}
67+
68+
```
69+
70+
This library is not limited to event types in aws-lambda-go; any event type (including your own custom ones) that as appropriate JSON mappings can be used.
71+

demux/entry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ func NewHandler(cfg *Cfg) any {
1010
return errorHandler(err)
1111
}
1212

13-
return func(ctx context.Context, rawEvent RawEvent) (any, error) {
13+
return func(ctx context.Context, rawEvent map[string]any) (any, error) {
1414
return processEvent(demuxCfg, ctx, rawEvent)
1515
}
1616
}

demux/event.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ import (
1111
type Factory func(ctx *EventContext) any
1212

1313
type EventContext struct {
14-
event RawEvent
15-
resourceContext RawResourceContext
14+
event map[string]any
15+
resourceContext map[string]any
1616
}
1717

1818
func processEvent(
1919
cfg *demuxCfg,
2020
ctx context.Context,
21-
rawEvent RawEvent) (any, error) {
21+
rawEvent map[string]any) (any, error) {
2222
event := createEvent(rawEvent, cfg.factories)
2323
if event == nil {
2424
return nil, errors.New("unable to determine event type for demux")
@@ -60,14 +60,14 @@ func processEvent(
6060
return returnValues[0].Interface(), nil
6161
}
6262

63-
func createEvent(rawEvent RawEvent, eventFactories []Factory) any {
63+
func createEvent(rawEvent map[string]any, eventFactories []Factory) any {
6464
if rawEvent == nil {
65-
rawEvent = RawEvent{}
65+
rawEvent = map[string]any{}
6666
}
6767

68-
rawResourceContext, ok := rawEvent["resourceContext"].(RawResourceContext)
68+
rawResourceContext, ok := rawEvent["resourceContext"].(map[string]any)
6969
if !ok {
70-
rawResourceContext = RawResourceContext{}
70+
rawResourceContext = map[string]any{}
7171
}
7272

7373
ctx := &EventContext{

demux/eventStruct.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
package demux
22

3-
type EventStruct map[string]any
4-
type RawEvent EventStruct
5-
6-
type RawResourceContext EventStruct
7-
8-
func (e EventStruct) HasAttribute(name string) bool {
3+
func HasAttribute(e map[string]any, name string) bool {
94
_, ok := e[name]
105
return ok
116
}
127

13-
func (e EventStruct) StringAttributeValue(name string) *string {
8+
func StringAttributeValue(e map[string]any, name string) *string {
149
v, ok := e[name]
1510
if !ok {
1611
return nil
@@ -24,8 +19,8 @@ func (e EventStruct) StringAttributeValue(name string) *string {
2419
return &vStr
2520
}
2621

27-
func (e EventStruct) StringAttributeMatches(name string, value string) bool {
28-
v := e.StringAttributeValue(name)
22+
func StringAttributeMatches(e map[string]any, name string, value string) bool {
23+
v := StringAttributeValue(e, name)
2924
if v == nil {
3025
return false
3126
}

demux/eventStruct_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,32 @@ import (
55
"testing"
66
)
77

8-
var mockEvent EventStruct = map[string]any{
8+
var mockEvent = map[string]any{
99
"abc": "def",
1010
"something": true,
1111
"somethingElse": 5,
1212
"nullValue": nil,
1313
}
1414

1515
func TestHasAttributeWorks(t *testing.T) {
16-
assert.True(t, mockEvent.HasAttribute("abc"))
17-
assert.False(t, mockEvent.HasAttribute("def"))
16+
assert.True(t, HasAttribute(mockEvent, "abc"))
17+
assert.False(t, HasAttribute(mockEvent, "def"))
1818
}
1919

2020
func TestStringAttributeValueWorks(t *testing.T) {
21-
v := mockEvent.StringAttributeValue("abc")
21+
v := StringAttributeValue(mockEvent, "abc")
2222
assert.NotNil(t, v)
2323
assert.Equal(t, "def", *v)
2424

25-
v = mockEvent.StringAttributeValue("something")
25+
v = StringAttributeValue(mockEvent, "something")
2626
assert.Nil(t, v)
2727

28-
v = mockEvent.StringAttributeValue("missingAttr")
28+
v = StringAttributeValue(mockEvent, "missingAttr")
2929
assert.Nil(t, v)
3030
}
3131

3232
func TestStringAttributeMatches(t *testing.T) {
33-
assert.True(t, mockEvent.StringAttributeMatches("abc", "def"))
34-
assert.False(t, mockEvent.StringAttributeMatches("abc", "xxxf"))
35-
assert.False(t, mockEvent.StringAttributeMatches("something", "true"))
33+
assert.True(t, StringAttributeMatches(mockEvent, "abc", "def"))
34+
assert.False(t, StringAttributeMatches(mockEvent, "abc", "xxxf"))
35+
assert.False(t, StringAttributeMatches(mockEvent, "something", "true"))
3636
}

demux/handler_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,18 +213,27 @@ func TestHandlerMapCreationFailsWithBadHandler(t *testing.T) {
213213
}
214214

215215
func foo() {
216-
h := &someHandler{}
217216
cfg := &Cfg{
218217
Factories: []Factory{
219218
func(ctx *EventContext) any {
220-
return nil
219+
if HasAttribute(ctx.event, "connectionId") {
220+
return &events.APIGatewayWebsocketProxyRequest{}
221+
}
222+
return &events.APIGatewayProxyRequest{}
221223
},
222224
},
223225
Handlers: []any{
224226
func(ctx context.Context, event *events.APIGatewayWebsocketProxyRequest) (
225227
*events.APIGatewayProxyResponse,
226228
error) {
227-
return h.HandleEvent(ctx, event)
229+
// TODO - your code here to handle websocket event
230+
return &events.APIGatewayProxyResponse{}, nil
231+
},
232+
func(ctx context.Context, event *events.APIGatewayProxyRequest) (
233+
*events.APIGatewayProxyResponse,
234+
error) {
235+
// TODO - your code here to handle HTTP/REST event
236+
return &events.APIGatewayProxyResponse{}, nil
228237
},
229238
},
230239
}

0 commit comments

Comments
 (0)