forked from aws-powertools/powertools-lambda-typescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget-by-id.ts
133 lines (109 loc) · 4.45 KB
/
get-by-id.ts
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
import { logger, tracer, metrics, LambdaInterface } from './common/powertools';
import { dynamodbClientV3, GetItemCommand } from './common/dynamodb-client';
import got from 'got';
/*
*
* This example uses the Method decorator instrumentation.
* Use TypeScript method decorators if you prefer writing your business logic using TypeScript Classes.
* If you aren’t using Classes, this requires the most significant refactoring.
* Find more Information in the docs: https://awslabs.github.io/aws-lambda-powertools-typescript/
*
*/
// Patch DynamoDB client for tracing
const docClient = tracer.captureAWSv3Client(dynamodbClientV3);
// Get the DynamoDB table name from environment variables
const tableName = process.env.SAMPLE_TABLE;
/**
*
* Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
* @param {Object} event - API Gateway Lambda Proxy Input Format
*
* Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
* @returns {Object} object - API Gateway Lambda Proxy Output Format
*
*/
class Lambda implements LambdaInterface {
@tracer.captureLambdaHandler()
@logger.injectLambdaContext({ logEvent: true })
@metrics.logMetrics()
public async handler(event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> {
if (event.httpMethod !== 'GET') {
throw new Error(`getById only accepts GET method, you tried: ${event.httpMethod}`);
}
// Tracer: Get facade segment created by AWS Lambda
const segment = tracer.getSegment();
// Tracer: Create subsegment for the function & set it as active
const handlerSegment = segment.addNewSubsegment(`## ${process.env._HANDLER}`);
tracer.setSegment(handlerSegment);
// Tracer: Annotate the subsegment with the cold start & serviceName
tracer.annotateColdStart();
tracer.addServiceNameAnnotation();
// Tracer: Add awsRequestId as annotation
tracer.putAnnotation('awsRequestId', context.awsRequestId);
// Metrics: Capture cold start metrics
metrics.captureColdStartMetric();
// Logger: Append awsRequestId to each log statement
logger.appendKeys({
awsRequestId: context.awsRequestId,
});
// Call the getUuid function
const uuid = await this.getUuid();
// Logger: Append uuid to each log statement
logger.appendKeys({ uuid });
// Tracer: Add uuid as annotation
tracer.putAnnotation('uuid', uuid);
// Metrics: Add uuid as metadata
metrics.addMetadata('uuid', uuid);
// Define response object
let response;
// Get the item from the table
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#get-property
try {
if (!tableName) {
throw new Error('SAMPLE_TABLE environment variable is not set');
}
if (!event.pathParameters) {
throw new Error('event does not contain pathParameters');
}
if (!event.pathParameters.id) {
throw new Error('PathParameter id is missing');
}
const data = await docClient.send(new GetItemCommand({
TableName: tableName,
Key: { id:
{
S: event.pathParameters.id
}
},
}));
const item = data.Item;
response = {
statusCode: 200,
body: JSON.stringify(item)
};
} catch (err) {
tracer.addErrorAsMetadata(err as Error);
logger.error('Error reading from table. ' + err);
response = {
statusCode: 500,
body: JSON.stringify({ 'error': 'Error reading from table.' })
};
}
// Tracer: Close subsegment (the AWS Lambda one is closed automatically)
handlerSegment.close(); // (## index.handler)
// Tracer: Set the facade segment as active again (the one created by AWS Lambda)
tracer.setSegment(segment);
// All log statements are written to CloudWatch
logger.info(`response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}`);
return response;
}
@tracer.captureMethod()
public async getUuid() {
// Request a sample random uuid from a webservice
const res = await got("https://httpbin.org/uuid");
return JSON.parse(res.body).uuid;
}
}
const handlerClass = new Lambda();
export const handler = handlerClass.handler.bind(handlerClass);