Reputation: 7312
I am trying to put together a really simple AWS Lambda using Serverless and DynamoDB.
My code to create an item is:
dynamoDb: DocumentClient
constructor() {
this.dynamoDb = new DynamoDB.DocumentClient({region: 'us-east-1'})
}
saveFiles(files: File[]): Promise<boolean> {
return new Promise<boolean>((resolve, reject ) => {
files.forEach(file => {
const tableName = process.env.DYNAMODB_TABLE
this.dynamoDb.put({
TableName: tableName,
Item: {
downloaded: {N : `${file.downloaded ? 1 : 0}`},
location: {S: `${file.location}`}
}
}, (error, result) => {
if (!!error) {
reject(error)
return
}
console.debug(`DB Save result: ${JSON.stringify(result)}`)
resolve(true)
})
})
})
}
The error is:
handler.ts:41
code:"ResourceNotFoundException"
message:"Requested resource not found"
name:"ResourceNotFoundException"
requestId:"2ST4DCE3NJ85UE32OAD6PUMTBJVV4KQNSO5AEMVJF66Q9ASUAAJG"
retryable:false
retryDelay:23.64284067311807
stack:"ResourceNotFoundException: Requested resource not found\n at Request.extractError (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/protocol/json.js:51:1)\n at Request.callListeners (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:106:1)\n at Request.emit (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/sequential_executor.js:78:1)\n at Request.emit (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/request.js:683:1)\n at Request.transition (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/request.js:22:1)\n at AcceptorStateMachine.runTo (/Users/michael/Development/javascript/data-export-lambda/.webpack/service/webpack:/node_modules/aws-sdk/lib/state_machine.js:14:1)\n at /Users/mi...
statusCode:400
When I query DynamoDB to list my tables I get:
aws dynamodb list-tables --endpoint-url http://localhost:8000
{
"TableNames": [
"data-export-scheduler-dev"
]
}
Table names definitely match:
My serverless.yaml is:
service:
name: data-export-scheduler
# Add the serverless-webpack plugin
plugins:
- serverless-webpack
- serverless-dynamodb-local
- serverless-offline
# serverless offline config
custom:
serverless-offline:
port: 4000
babelOptions:
presets: ["es2015"]
dynamodb:
stages:
- dev
start:
migrate: true
provider:
name: aws
region: us-east-1
runtime: nodejs8.10
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
functions:
exportAPI:
handler: handler.exportAPI
events:
- http:
method: post
path: export
resources:
Resources:
ExportDB:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
- AttributeName: location
AttributeType: S
KeySchema:
- AttributeName: location
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}
Does anyone know what I could be doing wrong? The tables is there and I can query it from the DynamoDB CLI, but I keep getting the ResourceNotFoundException when trying to query it from the code.
Update 1: When I run a query from the CLI I get the same error:
aws dynamodb query --table-name data-export-scheduler-dev --key-condition-expression "downloaded = :v1" --expression-attribute-values '{":v1": { "S" : "0"}}' $LOCAL
An error occurred (ResourceNotFoundException) when calling the Query operation: Requested resource not found
Upvotes: 2
Views: 4577
Reputation: 7215
By default, the AWS SDK looks up for resources in the Cloud. Therefore, when trying to connect to your DynamoDB instance, it is trying to connect to a DynamoDB table called data-export-scheduler-dev
located in us-east-1
as per your configuration.
You have to tell the SDK to look for a local DynamoDB instance, by defining the endpoint
attribute in its constructor.
Change:
constructor() {
this.dynamoDb = new DynamoDB.DocumentClient({region: 'us-east-1'})
}
to
constructor() {
this.dynamoDb = new DynamoDB.DocumentClient({region: 'us-east-1', endpoint: 'http://localhost:8000'})
}
Upvotes: 10