Skip to content

Commit 41c1ee2

Browse files
committed
Modified symlink
1 parent 103250b commit 41c1ee2

File tree

10 files changed

+354
-18
lines changed

10 files changed

+354
-18
lines changed

Diff for: examples/lambda-functions/get-by-id.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ export const getByIdHandler = async (event: APIGatewayProxyEvent, context: Conte
5959
throw new Error('SAMPLE_TABLE environment variable is not set');
6060
}
6161
if (!event.pathParameters) {
62-
throw new Error('event does not contain pathParameters')
62+
throw new Error('event does not contain pathParameters');
6363
}
6464
if (!event.pathParameters.id) {
65-
throw new Error('PathParameter id is missing')
65+
throw new Error('PathParameter id is missing');
6666
}
6767

6868
const data = await docClient.get({

Diff for: examples/lambda-functions/put-item.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export const putItemHandler = async (event: APIGatewayProxyEvent, context: Conte
5959
throw new Error('SAMPLE_TABLE environment variable is not set');
6060
}
6161
if (!event.body) {
62-
throw new Error('Event does not contain body')
62+
throw new Error('Event does not contain body');
6363
}
6464

6565
// Get id and name from the body of the request

Diff for: examples/sam/README.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This project contains source code and supporting files for a serverless applicat
44

55
This project includes the following files and folders:
66

7-
- `src/handlers` - Code for the application's Lambda function written in TypeScript. See "Prepare the project" below for instructions on how to copy the Lambda handler code here.
7+
- `src` - Code for the application's Lambda function written in TypeScript. See "Prepare the project" below for instructions on how to copy the Lambda handler code here.
88
- `events` - Invocation events that you can use to invoke the function.
99
- `template.yaml` - A template that defines the application's AWS resources.
1010

@@ -110,7 +110,7 @@ Build your application with the `sam build` command.
110110
sam build --beta-features
111111
```
112112

113-
The SAM CLI installs dependencies defined in `src/handlers/package.json`, compiles TypeScript with esbuild, creates a deployment package, and saves it in the `.aws-sam/build` folder.
113+
The SAM CLI installs dependencies defined in `package.json`, compiles TypeScript with esbuild, creates a deployment package, and saves it in the `.aws-sam/build` folder.
114114

115115
Test a single function by invoking it directly with a test event. An event is a JSON document that represents the input that the function receives from the event source. Test events are included in the `events` folder in this project.
116116

@@ -130,12 +130,12 @@ curl http://localhost:3000/
130130
The SAM CLI reads the application template to determine the API's routes and the functions that they invoke. The `Events` property on each function's definition includes the route and method for each path.
131131

132132
```yaml
133-
Events:
134-
HelloWorld:
135-
Type: Api
136-
Properties:
137-
Path: /
138-
Method: get
133+
Events:
134+
HelloWorld:
135+
Type: Api
136+
Properties:
137+
Path: /
138+
Method: get
139139
```
140140
141141
## Fetch, tail, and filter Lambda function logs

Diff for: examples/sam/src/get-all-items.ts

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
2+
import { Metrics } from '@aws-lambda-powertools/metrics';
3+
import { Logger } from '@aws-lambda-powertools/logger';
4+
import { Tracer } from '@aws-lambda-powertools/tracer';
5+
import { DocumentClient } from 'aws-sdk/clients/dynamodb';
6+
7+
// Create the PowerTools clients
8+
const metrics = new Metrics();
9+
const logger = new Logger();
10+
const tracer = new Tracer();
11+
12+
// Create DynamoDB DocumentClient and patch it for tracing
13+
const docClient = tracer.captureAWSClient(new DocumentClient());
14+
15+
// Get the DynamoDB table name from environment variables
16+
const tableName = process.env.SAMPLE_TABLE;
17+
18+
/**
19+
*
20+
* Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
21+
* @param {Object} event - API Gateway Lambda Proxy Input Format
22+
*
23+
* Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
24+
* @returns {Object} object - API Gateway Lambda Proxy Output Format
25+
*
26+
*/
27+
export const getAllItemsHandler = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> => {
28+
if (event.httpMethod !== 'GET') {
29+
throw new Error(`getAllItems only accepts GET method, you tried: ${event.httpMethod}`);
30+
}
31+
32+
// Tracer: Get facade segment created by AWS Lambda
33+
const segment = tracer.getSegment();
34+
35+
// Tracer: Create subsegment for the function & set it as active
36+
const handlerSegment = segment.addNewSubsegment(`## ${process.env._HANDLER}`);
37+
tracer.setSegment(handlerSegment);
38+
39+
// Tracer: Annotate the subsegment with the cold start & serviceName
40+
tracer.annotateColdStart();
41+
tracer.addServiceNameAnnotation();
42+
43+
// Tracer: Add annotation for the awsRequestId
44+
tracer.putAnnotation('awsRequestId', context.awsRequestId);
45+
46+
// Metrics: Capture cold start metrics
47+
metrics.captureColdStartMetric();
48+
49+
// Logger: Add persistent attributes to each log statement
50+
logger.addPersistentLogAttributes({
51+
awsRequestId: context.awsRequestId,
52+
});
53+
54+
// get all items from the table (only first 1MB data, you can use `LastEvaluatedKey` to get the rest of data)
55+
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#scan-property
56+
// https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html
57+
let response;
58+
try {
59+
if (!tableName) {
60+
throw new Error('SAMPLE_TABLE environment variable is not set');
61+
}
62+
63+
const data = await docClient.scan({
64+
TableName: tableName
65+
}).promise();
66+
const items = data.Items;
67+
68+
// Logger: All log statements are written to CloudWatch
69+
logger.debug(`retrieved items: ${items?.length || 0}`);
70+
71+
response = {
72+
statusCode: 200,
73+
body: JSON.stringify(items)
74+
};
75+
} catch (err) {
76+
tracer.addErrorAsMetadata(err as Error);
77+
logger.error('Error reading from table. ' + err);
78+
response = {
79+
statusCode: 500,
80+
body: JSON.stringify({ 'error': 'Error reading from table.' })
81+
};
82+
}
83+
84+
// Tracer: Close subsegment (the AWS Lambda one is closed automatically)
85+
handlerSegment.close(); // (## index.handler)
86+
87+
// Tracer: Set the facade segment as active again (the one created by AWS Lambda)
88+
tracer.setSegment(segment);
89+
90+
// All log statements are written to CloudWatch
91+
logger.info(`response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}`);
92+
93+
return response;
94+
};

Diff for: examples/sam/src/get-by-id.ts

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
2+
import { Metrics } from '@aws-lambda-powertools/metrics';
3+
import { Logger } from '@aws-lambda-powertools/logger';
4+
import { Tracer } from '@aws-lambda-powertools/tracer';
5+
import { DocumentClient } from 'aws-sdk/clients/dynamodb';
6+
7+
// Create the PowerTools clients
8+
const metrics = new Metrics();
9+
const logger = new Logger();
10+
const tracer = new Tracer();
11+
12+
// Create DynamoDB DocumentClient and patch it for tracing
13+
const docClient = tracer.captureAWSClient(new DocumentClient());
14+
15+
// Get the DynamoDB table name from environment variables
16+
const tableName = process.env.SAMPLE_TABLE;
17+
18+
/**
19+
*
20+
* Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
21+
* @param {Object} event - API Gateway Lambda Proxy Input Format
22+
*
23+
* Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
24+
* @returns {Object} object - API Gateway Lambda Proxy Output Format
25+
*
26+
*/
27+
28+
export const getByIdHandler = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> => {
29+
if (event.httpMethod !== 'GET') {
30+
throw new Error(`getById only accepts GET method, you tried: ${event.httpMethod}`);
31+
}
32+
// Tracer: Get facade segment created by AWS Lambda
33+
const segment = tracer.getSegment();
34+
35+
// Tracer: Create subsegment for the function & set it as active
36+
const handlerSegment = segment.addNewSubsegment(`## ${process.env._HANDLER}`);
37+
tracer.setSegment(handlerSegment);
38+
39+
// Tracer: Annotate the subsegment with the cold start & serviceName
40+
tracer.annotateColdStart();
41+
tracer.addServiceNameAnnotation();
42+
43+
// Tracer: Add annotation for the awsRequestId
44+
tracer.putAnnotation('awsRequestId', context.awsRequestId);
45+
46+
// Metrics: Capture cold start metrics
47+
metrics.captureColdStartMetric();
48+
49+
// Logger: Add persistent attributes to each log statement
50+
logger.addPersistentLogAttributes({
51+
awsRequestId: context.awsRequestId,
52+
});
53+
54+
// Get the item from the table
55+
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#get-property
56+
let response;
57+
try {
58+
if (!tableName) {
59+
throw new Error('SAMPLE_TABLE environment variable is not set');
60+
}
61+
if (!event.pathParameters) {
62+
throw new Error('event does not contain pathParameters');
63+
}
64+
if (!event.pathParameters.id) {
65+
throw new Error('PathParameter id is missing');
66+
}
67+
68+
const data = await docClient.get({
69+
TableName: tableName,
70+
Key: { id: event.pathParameters.id },
71+
}).promise();
72+
const item = data.Item;
73+
response = {
74+
statusCode: 200,
75+
body: JSON.stringify(item)
76+
};
77+
} catch (err) {
78+
tracer.addErrorAsMetadata(err as Error);
79+
logger.error('Error reading from table. ' + err);
80+
response = {
81+
statusCode: 500,
82+
body: JSON.stringify({ 'error': 'Error reading from table.' })
83+
};
84+
}
85+
86+
// Tracer: Close subsegment (the AWS Lambda one is closed automatically)
87+
handlerSegment.close(); // (## index.handler)
88+
89+
// Tracer: Set the facade segment as active again (the one created by AWS Lambda)
90+
tracer.setSegment(segment);
91+
92+
// All log statements are written to CloudWatch
93+
logger.info(`response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}`);
94+
95+
return response;
96+
};

Diff for: examples/sam/src/handlers

-1
This file was deleted.

Diff for: examples/sam/src/put-item.ts

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
2+
import { Metrics } from '@aws-lambda-powertools/metrics';
3+
import { Logger } from '@aws-lambda-powertools/logger';
4+
import { Tracer } from '@aws-lambda-powertools/tracer';
5+
import { DocumentClient } from 'aws-sdk/clients/dynamodb';
6+
7+
// Create the PowerTools clients
8+
const metrics = new Metrics();
9+
const logger = new Logger();
10+
const tracer = new Tracer();
11+
12+
// Create DynamoDB DocumentClient and patch it for tracing
13+
const docClient = tracer.captureAWSClient(new DocumentClient());
14+
15+
// Get the DynamoDB table name from environment variables
16+
const tableName = process.env.SAMPLE_TABLE;
17+
18+
/**
19+
*
20+
* Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
21+
* @param {Object} event - API Gateway Lambda Proxy Input Format
22+
*
23+
* Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
24+
* @returns {Object} object - API Gateway Lambda Proxy Output Format
25+
*
26+
*/
27+
28+
export const putItemHandler = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> => {
29+
if (event.httpMethod !== 'POST') {
30+
throw new Error(`putItem only accepts POST method, you tried: ${event.httpMethod}`);
31+
}
32+
// Tracer: Get facade segment created by AWS Lambda
33+
const segment = tracer.getSegment();
34+
35+
// Tracer: Create subsegment for the function & set it as active
36+
const handlerSegment = segment.addNewSubsegment(`## ${process.env._HANDLER}`);
37+
tracer.setSegment(handlerSegment);
38+
39+
// Tracer: Annotate the subsegment with the cold start & serviceName
40+
tracer.annotateColdStart();
41+
tracer.addServiceNameAnnotation();
42+
43+
// Tracer: Add annotation for the awsRequestId
44+
tracer.putAnnotation('awsRequestId', context.awsRequestId);
45+
46+
// Metrics: Capture cold start metrics
47+
metrics.captureColdStartMetric();
48+
49+
// Logger: Add persistent attributes to each log statement
50+
logger.addPersistentLogAttributes({
51+
awsRequestId: context.awsRequestId,
52+
});
53+
54+
// Creates a new item, or replaces an old item with a new item
55+
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#put-property
56+
let response;
57+
try {
58+
if (!tableName) {
59+
throw new Error('SAMPLE_TABLE environment variable is not set');
60+
}
61+
if (!event.body) {
62+
throw new Error('Event does not contain body');
63+
}
64+
65+
// Get id and name from the body of the request
66+
const body = JSON.parse(event.body);
67+
const id = body.id;
68+
const name = body.name;
69+
70+
await docClient.put({
71+
TableName: tableName,
72+
Item: { id: id, name: name }
73+
}).promise();
74+
response = {
75+
statusCode: 200,
76+
body: JSON.stringify(body)
77+
};
78+
} catch (err) {
79+
tracer.addErrorAsMetadata(err as Error);
80+
logger.error('Error writing data to table. ' + err);
81+
response = {
82+
statusCode: 500,
83+
body: JSON.stringify({ 'error': 'Error writing data to table.' })
84+
};
85+
}
86+
87+
// Tracer: Close subsegment (the AWS Lambda one is closed automatically)
88+
handlerSegment.close(); // (## index.handler)
89+
90+
// Tracer: Set the facade segment as active again (the one created by AWS Lambda)
91+
tracer.setSegment(segment);
92+
93+
// All log statements are written to CloudWatch
94+
logger.info(`response from: ${event.path} statusCode: ${response.statusCode} body: ${response.body}`);
95+
96+
return response;
97+
};

Diff for: examples/sam/src/tsconfig.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"compilerOptions": {
3+
"experimentalDecorators": true,
4+
"noImplicitAny": true,
5+
"target": "ES2020",
6+
"module": "commonjs",
7+
"declaration": true,
8+
"declarationMap": true,
9+
"outDir": "lib",
10+
"removeComments": false,
11+
"strict": true,
12+
"inlineSourceMap": true,
13+
"moduleResolution": "node",
14+
"resolveJsonModule": true,
15+
"pretty": true,
16+
"esModuleInterop": true
17+
},
18+
"exclude": [ "./node_modules"],
19+
"watchOptions": {
20+
"watchFile": "useFsEvents",
21+
"watchDirectory": "useFsEvents",
22+
"fallbackPolling": "dynamicPriority"
23+
},
24+
"lib": [ "es2020" ],
25+
"types": [
26+
"node"
27+
]
28+
}

0 commit comments

Comments
 (0)