Greetings!
In the previous post, I described how to create a serverless REST API using the serverless framework in which we discussed the project setup and the create operation. In this post, we will complete other operations of our API.
In the previous post, I described how to create a serverless REST API using the serverless framework in which we discussed the project setup and the create operation. In this post, we will complete other operations of our API.
You can find the complete source code here.
Happy learning ☺
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.ReadItem.html
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.UpdateItem.html
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.DeleteItem.html
https://www.udemy.com/course/building-rest-apis-with-serverless/
Read Item(s)
As we created an item in our previous post, we had to check the value using the AWS console. Now it is time to access items via the REST endpoint.Get all books/items
When we define APIs for fetching, we use the "get" HTTP method. As we select all the books, we use the DynamoDB scan command hence we need to allow access to it.Get all handler definition
getBooks:
handler: src/get-books.handler
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Scan
Resource: !GetAtt crudDynamoDBTable.Arn
events:
- http:
path: /books
method: get
cors: true
Get all handler implementation
Create a new module under the src folder as get-books.js. This code is very simple."use strict";
import { ScanCommand } from "@aws-sdk/lib-dynamodb";
import { response } from "./utils.js";
import { ddbDocClient, CRUD_TABLE_NAME } from "./database.js";
export const handler = async (event) => {
try {
const params = {
TableName: CRUD_TABLE_NAME
};
const data = await ddbDocClient.send(new ScanCommand(params));
return response(200, data.Items);
} catch (err) {
console.log("Error", err);
return response(500, { message: err.message });
}
}
Get a single book/item
This is the read operation of our crud. As we use the get operation of the DynamoDB, we need to allow GetItem action to our Lambda function. Another notable difference is the use of path parameters. The notation is to use brackets as below./books/{id}
Get handler definition
getBook:
handler: src/get-book.handler
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:GetItem
Resource: !GetAtt crudDynamoDBTable.Arn
events:
- http:
path: /books/{id}
method: get
cors: true
Get handler implementation
Create a new module under the src folder as get-book.js. We use GetCommand to retrieve a book. Another thing to learn here is how we can access path parameters.event.pathParameters.id
"use strict";
import { GetCommand } from "@aws-sdk/lib-dynamodb";
import { response } from "./utils.js";
import { ddbDocClient, CRUD_TABLE_NAME } from "./database.js";
export const handler = async (event) => {
try {
const bookId = event.pathParameters.id;
const params = {
TableName: CRUD_TABLE_NAME,
Key: {
bookId,
},
};
const data = await ddbDocClient.send(new GetCommand(params));
return response(200, data.Item);
} catch (err) {
console.log("Error", err);
return response(500, { message: err.message });
}
};
Update an item
Once we create an item, we would like to update it as well. Defining the handler in serverless.yml is simple for all these operations. Things to note here is we are allowing UpdateItem action to the Lambda function as this is an update operation. Another thing to note is the HTTP method. We use the "put" HTTP method as this is an update operation.Update handler definition
updateBook:
handler: src/update-book.handler
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:UpdateItem
Resource: !GetAtt crudDynamoDBTable.Arn
events:
- http:
path: /books/{id}
method: put
cors: true
Update handler implementation
This is a little lengthy compared to other handlers. We need to define the update statement using "UpdateExpression" and explain it to the DynamoDB client using "Expression" properties. Create a new module under src as update-book.js"use strict";
import { UpdateCommand } from "@aws-sdk/lib-dynamodb";
import { response } from "./utils.js";
import { ddbDocClient, CRUD_TABLE_NAME } from "./database.js";
export const handler = async (event) => {
try {
const bookId = event.pathParameters.id;
const book = JSON.parse(event.body);
const params = {
TableName: CRUD_TABLE_NAME,
Key: {
bookId,
},
UpdateExpression: "set #title = :title, #author = :author",
ExpressionAttributeNames: {
"#title": "title",
"#author": "author",
},
ExpressionAttributeValues: {
":title": book.title,
":author": book.author,
},
ConditionExpression: "attribute_exists(bookId)",
};
const data = await ddbDocClient.send(new UpdateCommand(params));
return response(200, { message: `Book updated for ${bookId}` });
} catch (err) {
console.log("Error", err);
return response(500, { message: err.message });
}
};
Delete an item
And finally, our last operation is to delete an item. This is very similar to the read operation other that used the HTTP method and the DynamoDB operation.Delete handler definition
deleteBook:
handler: src/delete-book.handler
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DeleteItem
Resource: !GetAtt crudDynamoDBTable.Arn
events:
- http:
path: /books/{id}
method: delete
cors: true
Delete handler implementation
Create a new module under src as delete-book.js and use the below code."use strict";
import { DeleteCommand } from "@aws-sdk/lib-dynamodb";
import { response } from "./utils.js";
import { ddbDocClient, CRUD_TABLE_NAME } from "./database.js";
export const handler = async (event) => {
try {
const bookId = event.pathParameters.id;
const params = {
TableName: CRUD_TABLE_NAME,
Key: {
bookId,
},
};
const data = await ddbDocClient.send(new DeleteCommand(params));
return response(204, { message: `Book is deleted for ${bookId}` });
} catch (err) {
console.log("Error", err);
return response(500, { message: err.message });
}
};
Clean up
Remember to delete your services. We do not have to do this manually as the serverless framework provides a single command.serverless remove
Conclusion
This ends our basic RESTful CRUD API using AWS serverless services. We have learned how to use the serverless framework as well.Happy learning ☺
References
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.Scan.htmlhttps://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.ReadItem.html
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.UpdateItem.html
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.DeleteItem.html
https://www.udemy.com/course/building-rest-apis-with-serverless/
Comments
Post a Comment