32-43
(32) section intro (33) put item
npm i @types/aws-lambda
(34) getting data from ApiGateway
const item = typeof event.body == 'object' ? event.body : JSON.parse(event.body)
>? why this check for parsing? is this testing only, or is this random in prod?
(35-36) DynamoDB + lambda
// create table
const table = new Table(this.stack, this.props.tableName, {
partitionKey: {
name: this.props.primaryKey,
type: AttributeType.STRING,
},
tableName: this.props.tableName
})
// create lambda
const id = `${this.props.tableName}-${lambdaName}`;
const createLambda = new NodejsFunction(this.stack, id, {
entry: (join(__dirname, '..', 'services', this.props.tableName, `${lambdaName}.ts`)),
handler: 'handler',
functionName: id,
environment: {
TABLE_NAME: this.props.tableName,
PRIMARY_KEY: this.props.primaryKey,
}
})
// create integration
const createLambdaIntegration = new LambdaIntegration(createLambda)
// grant table rights to lambda
table.grantWriteData(createLambda)
// table.grantReadData(readLambda)
// add to api gateway
const spaceResource = this.api.root.addResource('spaces');
spaceResource.addMethod('POST', this.spacesTable.createLambdaIntegration)
(37) Scan operation
const queryResponse = await dbClient.scan({
TableName: TABLE_NAME,
}).promise()
(38) Query Operation
const queryResponse = await dbClient.query({
TableName: TABLE_NAME,
KeyConditionExpression: '#zz = :zzzz',
ExpressionAttributeNames: {
'#zz': PRIMARY_KEY,
},
ExpressionAttributeValues: {
':zzzz': keyValue,
},
}).promise();
(39) Query on secondary indexes
const queryResponse = await dbClient.query({
TableName: TABLE_NAME,
KeyConditionExpression: '#zz = :zzzz',
ExpressionAttributeNames: {
'#zz': PRIMARY_KEY,
},
ExpressionAttributeValues: {
':zzzz': keyValue,
},
}).promise();
(40) Update Operation
const updateResult = await dbClient.update({
TableName: TABLE_NAME,
Key: {
[PRIMARY_KEY]: spaceId
},
UpdateExpression: 'set #zzzNew = :new',
ExpressionAttributeNames: {
'#zzzNew': requestBodyKey
},
ExpressionAttributeValues: {
':new': requestBodyValue
},
ReturnValues: 'UPDATED_NEW',
}).promise()
(41) Delete Operation
const deleteResult = await dbClient.delete({
TableName: TABLE_NAME,
Key: {
[PRIMARY_KEY]: spaceId
},
}).promise()
(42) Data Validation Concepts like ‘interfaces’ and ’types’ are not available at runtime.
runtime type validation is like a missing feature of typescript
options:
- custom errors + Typescript: Type Guards
- …
export interface Space {
spaceId: string
name: string,
location: string,
photoUrl?: string,
}
export class MissingFieldError extends Error {}
export function validateAsSpaceEntry(arg:any) {
if(!(arg as Space).name) {
throw new MissingFieldError('Value for name required!')
}
if(!(arg as Space).location) {
throw new MissingFieldError('Value for location required!')
}
if(!(arg as Space).spaceId) {
throw new MissingFieldError('Value for spaceId required!')
}
}
(43) refactors a) uuid
import {v4} from "uuid";
this means the WHOLE uuid lib will be packaged up for the lambda this library does not allow to `from “uuid/v4”`