-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
117 lines (103 loc) · 4.22 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
apiv1 "github.com/alec-rabold/course-data-api/pkg/api/v1"
"github.com/alec-rabold/course-data-api/pkg/client/ellucian"
"github.com/alec-rabold/course-data-api/pkg/crawler"
model "github.com/alec-rabold/course-data-api/pkg/model/request"
"github.com/alec-rabold/course-data-api/pkg/router"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/go-logr/logr"
"github.com/go-logr/zapr"
"github.com/mitchellh/mapstructure"
"go.uber.org/zap"
)
// Version is set at build-time through the Makefile
var Version = "unknown"
func main() {
lambda.Start(handleRequest)
}
func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
log, ctx, err := initalizeLogger(ctx)
if err != nil {
return events.APIGatewayProxyResponse{}, fmt.Errorf("failed to instantiate logger: %v", err)
}
log.Info("incoming request", "request", request, "version", Version)
r := newRouter()
return r.Handle(ctx, request)
}
// TODO: the parameters handling can probably be built into the router
func newRouter() *router.Router {
r := router.NewRouter(apiv1.BasePath)
// Currently only Ellucian Banner is supported so default to it here
client := ellucian.NewClient(crawler.NewCrawler())
r.Route(http.MethodGet, apiv1.PathColleges, func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
return marshalResponse(client.GetColleges(ctx))
})
r.Route(http.MethodGet, apiv1.PathTerms, func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
var requestModel model.Terms
if err := mapstructure.Decode(request.QueryStringParameters, &requestModel); err != nil {
return handleError(fmt.Errorf("error decoding request parameters: %v", err))
}
return marshalResponse(client.GetTerms(ctx, requestModel))
})
r.Route(http.MethodGet, apiv1.PathSubjects, func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
var requestModel model.Subjects
if err := mapstructure.Decode(request.QueryStringParameters, &requestModel); err != nil {
return handleError(fmt.Errorf("error decoding request parameters: %v", err))
}
return marshalResponse(client.GetSubjects(ctx, requestModel))
})
r.Route(http.MethodGet, apiv1.PathCourses, func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
var requestModel model.Courses
if err := mapstructure.Decode(request.QueryStringParameters, &requestModel); err != nil {
return handleError(fmt.Errorf("error decoding request parameters: %v", err))
}
return marshalResponse(client.GetCourses(ctx, requestModel))
})
r.Route(http.MethodGet, apiv1.PathSections, func(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
var requestModel model.Sections
if err := mapstructure.Decode(request.QueryStringParameters, &requestModel); err != nil {
return handleError(fmt.Errorf("error decoding request parameters: %v", err))
}
return marshalResponse(client.GetSections(ctx, requestModel))
})
return r
}
// Helper method to marshal data returned by the API client into an API Gateway Proxy Response
func marshalResponse(data interface{}, handlerErr error) (events.APIGatewayProxyResponse, error) {
if handlerErr != nil {
return handleError(handlerErr)
}
b, err := json.Marshal(data)
if err != nil {
return handleError(err)
}
return events.APIGatewayProxyResponse{
StatusCode: http.StatusOK,
Body: string(b),
}, nil
}
// Helper method to return errors as an API Gateway Proxy Response
func handleError(err error) (events.APIGatewayProxyResponse, error) {
return events.APIGatewayProxyResponse{
StatusCode: http.StatusInternalServerError,
Body: "the server has encountered an unexpected error",
}, err
}
func initalizeLogger(ctx context.Context) (*logr.Logger, context.Context, error) {
zLog, err := zap.NewProduction()
if err != nil {
return nil, nil, err
}
ctx = logr.NewContext(ctx, zapr.NewLogger(zLog))
log, err := logr.FromContext(ctx)
if err != nil {
return nil, nil, err
}
return &log, ctx, nil
}