-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathhandler.ts
More file actions
80 lines (71 loc) · 2.84 KB
/
handler.ts
File metadata and controls
80 lines (71 loc) · 2.84 KB
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
import {APIGatewayProxyResult} from "aws-lambda"
import middy from "@middy/core"
import {MiddlewareApplicator} from "./middleware"
import {Logger} from "@aws-lambda-powertools/logger"
import {Result} from "pratica"
import {Bundle, Task} from "fhir/r4"
import {wrap_with_status} from "./utils"
export type Validator<Event, Message> = (event: Event, logger: Logger) => Result<Message, APIGatewayProxyResult>
export type Transformer<Message> = (requestBody: Message, logger: Logger) => Result<Bundle<Task>, APIGatewayProxyResult>
type EventWithHeaders = {
headers: {
"nhsd-correlation-id"?: string
"nhsd-request-id"?: string
"x-correlation-id"?: string
"apigw-request-id"?: string
}
}
type HandlerConfig<Event, Message> = {
middleware: Array<MiddlewareApplicator>
params: HandlerParams<Event, Message>
logger: Logger
schema?: object
}
export type HandlerParams<Event, Message> = {
validator: Validator<Event, Message>
transformer: Transformer<Message>
}
/**
* Generic handler for all lambda functions.
* Validates the incoming event then transforms it into a response.
*/
async function generic_handler<Event extends EventWithHeaders, Message>(
event: Event,
params: HandlerParams<Event, Message>,
logger: Logger
): Promise<APIGatewayProxyResult> {
append_headers(event.headers, logger)
const validator = (event: Event) => params.validator(event, logger)
const transformer = (requestBody: Message) => params.transformer(requestBody, logger)
return validator(event).chain(transformer).map(wrap_with_status(200, event.headers)).value()
}
function append_headers(headers: Record<string, string>, logger: Logger) {
const headers_to_append: Record<string, string> = {}
if (headers["apigw-request-id"]) {
headers_to_append["apigw-request-id"] = headers["apigw-request-id"]
}
if (headers["nhsd-correlation-id"]) {
headers_to_append["nhsd-correlation-id"] = headers["nhsd-correlation-id"]
}
if (headers["nhsd-request-id"]) {
headers_to_append["nhsd-request-id"] = headers["nhsd-request-id"]
}
if (headers["x-correlation-id"]) {
headers_to_append["x-correlation-id"] = headers["x-correlation-id"]
}
if (headers["x-request-id"]) {
headers_to_append["x-request-id"] = headers["x-request-id"]
}
logger.appendKeys(headers_to_append)
logger.info("added headers to logger for tracing", {headers_to_append})
}
/**
* Creates a new Lambda handler with the specified handler function and middleware.
*/
export const newHandler = <Event extends EventWithHeaders, Message>(handlerConfig: HandlerConfig<Event, Message>) => {
let newHandler = middy((event: Event) => generic_handler(event, handlerConfig.params, handlerConfig.logger))
for (const middleware_applicator of handlerConfig.middleware) {
newHandler = middleware_applicator(newHandler, handlerConfig.logger, handlerConfig.schema)
}
return newHandler
}