AWS Amplify를 사용하여 TODO 애플리케이션의 백엔드 작성

개시하다


이런 환경에서 활동하는 람다의 루비 코드를 썼다고 한다.백엔드 서비스 구축 자체저번는 앰플리파이로 대충 만들어졌고, 램다의 운행시간을 루비로 교체[1]
            ┌──────────┐      ┌──────────┐     ┌──────────┐
            │          │      │  Lambda  │     │          │
Client───────►  APIGW  ├──────►   with   ├─────► DynamoDB │
            │  (REST)  │      │  RubySDK │     │          │
            └──────────┘      └──────────┘     └──────────┘

API


TODO 어플리케이션이기 때문에 APIGW의 REST API의 정의는 이렇습니다.
GET /tasks         List all tasks
GET /task/1        Get a task by id
POST /tasks        Create new task
PUT /tasks         Update a task
DELETE /tasks/1    Delete a task by id
APIGW의 설정 자체는 Amplify가 하는데 콘솔에서 보면 이런 설정이다.
 /                        
 |_ /todos        Main resource. Eg: /todos
    ANY           Methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
    OPTIONS       Allow pre-flight requests in CORS by browser
    |_ /{proxy+}  Eg: /todos/, /todos/id
       ANY        Methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
       OPTIONS    Allow pre-flight requests in CORS by browser
ANY에서 모든 HTTP 방법을 일치시키고 Lambda proxy integrations에서 요구를 Lambda에 직접 넣습니다.또한 {proxy+} URL과 일치하는 모든 경로 매개 변수 /tasks/100 를 사용하면 이것도 Lambda측에 넘깁니다
고객이 보낸 데이터는 이런 느낌입니다.
payload
{
    "task-id": "30",
    "is-active": true,
    "task-name": "Buy some coffee",
    "updated-at": 1616047389,
    "created-at": 1616047389,
    "user-id": "110"
}

DynamoDB


Amplify에서 task-id를 키로 테이블 만들기todoTable-dev[1:1]

Lambda


APIGW 설정에 따라 램바다 측 코드는 이런 느낌이다.Ruby는 2.7lambda_handler.rb
require 'json'
require 'json/add/exception' #...❶
require 'aws-sdk-dynamodb'

def add_task(table, body)
  begin
    table.put_item({ item: body })  
    list_task(table)
  rescue => e
    { statusCode: 500, body: e.to_json } #...❶
  end
end

def delete_task(table, task_id)
  begin
    params = { table_name: table, key: { 'task-id': task_id } }
    table.delete_item(params)
    list_task(table)
  rescue => e
    { statusCode: 500, body: e.to_json }
  end
end

def update_task(table, body)
  begin
    params = {
      table_name: table,
      key: { 'task-id': body['task-id'] },
      attribute_updates: { #...❷
        'is-active': { value: body['is-active'], action: "PUT" },
        'task-name': { value: body['task-name'], action: "PUT" },
        'updated-at': { value: body['updated-at'], action: "PUT" }
      }
    }
    table.update_item(params)  
    list_task(table)
  rescue => e
    { statusCode: 500, body: e.to_json }
  end
end

def list_task(table)
  begin
    scan_output = table.scan({ limit: 50, select: "ALL_ATTRIBUTES" })
    { statusCode: 200, body: JSON.generate(scan_output['items']) }
  rescue => e
    { statusCode: 500, body: e.to_json }
  end
end

def get_task(table, task_id)
  begin
    params = { key: { 'task-id': task_id } }
    task = table.get_item(params)
    { statusCode: 200, body: JSON.generate(task['item']) }
  rescue => e
    { statusCode: 500, body: e.to_json }
  end
end

def lambda_handler(event:, context:)
  begin
    http_method = event['httpMethod']
    dynamodb = Aws::DynamoDB::Resource.new(region: 'us-east-2')
    table = dynamodb.table('todoTable-dev')
    
    case http_method
      when 'GET'
        path_param = event.dig('pathParameters', 'proxy') #...❸
        if path_param.nil?
          list_task(table)
        else
          get_task(table, path_param) 
        end
      when 'PUT'    then update_task(table, JSON.parse(event['body']))
      when 'POST'   then result = add_task(table, JSON.parse(event['body']))
      when 'DELETE' then delete_task(table, event['pathParameters']['proxy']) #...❸
      else 0
    end
  rescue => e
    { statusCode: 500, body: e.to_json }
  end
end
  • 이상이 발생했을 때Internal Server Error 오류 내용을 Exception#to_json로 고객에게 되돌려줍니다.사용하기 위해Exception#to_json, 필요require 'json/add/exception'.생산 중에는 할 수 없습니다
  • DynamoDB의 값 업데이트attribute_updates에서 추천하지 않는 것 같습니다.추천UpdateExpression이지만 이 기술은 귀찮아요
  • 클라이언트-APIGW의 Path Parameter에서 진입event['pathParameters']['proxy'].있을 수 있음nil이므로 사용dig을 통해 키 없이 오류가 발생하지 않고 반환nil
  • 이런 느낌으로 잠시 움직였습니다!웹 애플리케이션을 만드는 것도 점점 어려워지고 있어요.

    사이트 축소판 그림


    https://gerard-sans.medium.com/create-a-rest-api-integrated-with-amazon-dynamodb-using-aws-amplify-and-vue-5be746e43c22
    https://zenn.dev/masaino/articles/8f9b6aaf9ed8bb
    각주
    자세한 건 이쪽을 보세요. ↩︎ ↩︎

    좋은 웹페이지 즐겨찾기