Full Stack Serverless Challenge #1: AWS Amplify Gen 2

Raphael Jambalos - Jun 29 - - Dev Community

In this challenge, we'll be learning more about Amplify Gen 2. It is an AWS service that allows front-end developers to deploy full-stack applications. It has a code library that attaches itself to supported frontend frameworks like VueJS, ReactJS, Flutter, React Native, etc. Once attached to the framework, developers can easily create serverless backends, protect them with user authentication, and add file uploads and downloads.

We start by following the basic getting started guide. From there, we'll get our hands dirty with the core functionalities of Amplify Gen 2.

This is not a walkthrough post. It forces you to explore on your own by giving a challenge to follow.

About the Full Stack Serverless Challenge Series

In this series, I'll try out many full-stack serverless offerings in the market. I'll be doing:

  • AWS Amplify Gen 2 (we're here)
  • Ion + SST
  • and more...!

[A] Basic Amplify Gen 2

For this section, we would follow the getting started tutorial. It is quite straightforward and is doable within 30 minutes. By the end, you should be able to use the Getting Started repository to:

  • Create todo list
  • Delete todo list
  • Have a login via Cognito
  • Each unique user has their own set of todo list

Your output should look like this:

Image description

Answer the following questions:

  1. The todo list is stored where? What backend powers the APIs?
  2. What does npx ampx sandbox do? Is it a local environment? Does it deploy to the cloud?
  3. How do you deploy an Amplify project?

[B] Amplify Data + Amplify Functions + Amplify Storage Basics

  • Allow users to add comments for each todo task. This involves duplicating how the todo list schema was created and making an exact duplicate for comment.
  • For each todo task, add capacity to add file attachments. These attachments should use Amplify Files. Once uploaded, the s3 URL and the taskID are sent to a Lambda function deployed using Amplify Functions. It should access a DynamoDB table using the aws-sdk library, and create an entry that associates that image_path with the todo task id. The DynamoDB, APIGW, and Lambda functions are all deployed using CDK.
  • Create an API that allows you to see all the attachments associated with each todo task. Integrate it with your frontend.

This is my version:

Image description

Answer the following questions:

  1. How do you add JS packages for Amplify functions?
  2. Where do we get permission to upload files?
  3. When we preview the files, are there any security features used?
  4. How is the experience working with basic CDK? Can you use higher-level constructs to accelerate this?
  5. Cloudformation has a problem that each stack has a limit of 500 resources. How is that mitigated in CDK?
  6. How do you represent relationships when using a database like DynamoDB?
  7. Explore the concept of Single Table Design for dynamodb. How is it different from the approach here?

[C] Above and Beyond!

Here are above and beyond hands-on that you can try with AWS Amplify. I haven't tried them myself, but scanning through the docs, I thought these are interesting features that I might go back to later. And if you have more time, I encourage you to do it as well:

Appendix A: Hints

There are instances where I got stuck. You might find this section useful as you go through the exercise.

A1: Adding package

This allows you to include packages in your backend functions



cd amplify
npm install @aws-sdk/client-dynamodb

Enter fullscreen mode Exit fullscreen mode




A2: Adding environment variables

This allows you to pass on environment variables to your lambda functions:



import { Function } from 'aws-cdk-lib/aws-lambda';

const backend = defineBackend({
auth,
data,
sayHello,
storage
});

// create a new API stack
const apiStack = backend.createStack("api-stack");

const table = new Table(apiStack, 'AttachmentTable12345', {
partitionKey: {
name: 'id',
type: AttributeType.STRING,
}
});

const lambdaFunction = backend.sayHello.resources.lambda as Function;
lambdaFunction.addEnvironment('DYNAMODB_TABLE_NAME_MASTER', 'AttachmentTable12345');

Enter fullscreen mode Exit fullscreen mode




A3: Use ref() to make the elements binded

The variant of VueJS used does not respond to typical v-binding. I found that using ref() works best.



let commentData = ref({})
const currentId = ref("")

async function showCommentsV2(todoId: string) {
console.log("entering showCommentsV2")
currentId.value = todoId;

client.models.Comment.listCommentByTodo_parent_id({
todo_parent_id: todoId
}).then((d) => {
console.log("BEFORE DATA IS")
console.log(commentData)
console.log("d")
console.log(d)
commentData.value = d.data
console.log("AFTER DATA IS")
console.log(commentData)
})
}

Enter fullscreen mode Exit fullscreen mode




A4: Ultimate Hint - The Github Repo

I encourage you to use this as last resort. This contains the answer for Challenge A and B already. I recommend that you start with the repository given in the AWS Getting Started Guide, and use your wits solve Challenge B and C.

That's all!

Let me know if you made this far, or if you have any questions! Would love to hear from you

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .