---
# System prepended metadata

title: 'TODO-LIST實作, Serverless, Next.js'

---

# TODO-LIST實作, Serverless, Next.js

前言
> 這次延續之前的Serverless框架快速部署Create, Read, ~~Update, Delete~~(CRUD)的API功能來與AWS DynamoDB 互動並完成一個簡單的TO-DO List
> 由於一些技術上的困難 這次只會實作Create, Read 跟 Delete 到前端..

>可以改進的: 加入身分認證機制, 前端render的速度 
## System Overview
![](https://i.imgur.com/QMgju4G.png)

## Getting Started
點擊AWS右上角User / Security credentials / Access keys
```
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
```


## Development

### Back-end
1. Install **Serverless Framework**
```
npm install -g serverless 
```
3. Use template to create a serverless project
```bash
serverless create --template-url=https://github.com/Ianpengg/Todo-list-serverless/tree/main/backend
cd backend
```
3. Set **AWS credentials** 
```
export AWS_ACCESS_KEY_ID=**********
export AWS_SECRET_ACCESS_KEY=***********
(For Windows)
set AWS_ACCESS_KEY_ID=**********
set AWS_SECRET_ACCESS_KEY=***********
```
4. Check the **serverless.yml**
```yml
service: python-rest-dynamodb

frameworkVersion: ">=2.24.0"

provider:
  name: aws
  runtime: python3.8
  region: us-east-1
  environment:
    DYNAMODB_TABLE: ${self:service}-${sls:stage}
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - dynamodb:Query
            - dynamodb:Scan
            - dynamodb:GetItem
            - dynamodb:PutItem
            - dynamodb:UpdateItem
            - dynamodb:DeleteItem
          Resource: "arn:aws:dynamodb:${aws:region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"

functions:
  create:
    handler: todos/create.create
    events:
      - http:
          path: todos
          method: post
          cors: true

  list:
    handler: todos/list.list
    events:
      - http:
          path: todos
          method: get
          cors: true

  get:
    handler: todos/get.get
    events:
      - http:
          path: todos/{id}
          method: get
          cors: true

  update:
    handler: todos/update.update
    events:
      - http:
          path: todos/{id}
          method: put
          cors: true

  delete:
    handler: todos/delete.delete
    events:
      - http:
          path: todos/{id}
          method: delete
          cors: true

resources:
  Resources:
    TodosDynamoDbTable:
      Type: "AWS::DynamoDB::Table"
      DeletionPolicy: Retain
      Properties:
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:provider.environment.DYNAMODB_TABLE}
```
5. deploy 
```
serverless deploy
```
If the deployment success you should see:
```
Serverless: Packaging service…
Serverless: Uploading CloudFormation file to S3…
Serverless: Uploading service .zip file to S3…
Serverless: Updating Stack…
Serverless: Checking Stack update progress…
Serverless: Stack update finished…

Service Information
service: serverless-rest-api-with-dynamodb
stage: dev
region: us-east-1
api keys:
  None
endpoints:
  POST - https://45wf34z5yf.execute-api.us-east-1.amazonaws.com/dev/todos
  GET - https://45wf34z5yf.execute-api.us-east-1.amazonaws.com/dev/todos
  GET - https://45wf34z5yf.execute-api.us-east-1.amazonaws.com/dev/todos/{id}
  PUT - https://45wf34z5yf.execute-api.us-east-1.amazonaws.com/dev/todos/{id}
  DELETE - https://45wf34z5yf.execute-api.us-east-1.amazonaws.com/dev/todos/{id}
functions:
  serverless-rest-api-with-dynamodb-dev-update: arn:aws:lambda:us-east-1:488110005556:function:serverless-rest-api-with-dynamodb-dev-update
  serverless-rest-api-with-dynamodb-dev-get: arn:aws:lambda:us-east-1:488110005556:function:serverless-rest-api-with-dynamodb-dev-get
  serverless-rest-api-with-dynamodb-dev-list: arn:aws:lambda:us-east-1:488110005556:function:serverless-rest-api-with-dynamodb-dev-list
  serverless-rest-api-with-dynamodb-dev-create: arn:aws:lambda:us-east-1:488110005556:function:serverless-rest-api-with-dynamodb-dev-create
  serverless-rest-api-with-dynamodb-dev-delete: arn:aws:lambda:us-ea
```

### Front-end
1. Get the front-end repository
```bash
git clone https://github.com/Ianpengg/Todo-list-serverless.git
cd Todo-list-serverless
git checkout front-end
```
2. Install required packages
```
npm install
```
3. Check the front-end
```
npm run dev
```
you should see:
![](https://i.imgur.com/kliXLMQ.png)

Now you can type the task in input box and the page should reload and get the update todo-list


### Bug may encountered
1. **403 forbidden**
https://cors-anywhere.herokuapp.com/
![](https://i.imgur.com/dV3e1gu.png)
2. **data is not a function**
remove the `data = data['Items']` in the index.js

## Reference 
1. [這次實作的Github](https://github.com/Ianpengg/Todo-list-serverless)
2. [Chatgpt](https://openai.com/blog/chatgpt/)
3. [Serverless Framework](https://www.serverless.com/)
4. [Next.js](https://nextjs.org/)
5. [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)