[LAMBDA]사용자 IP정보 저장/조회(POST/GET)

박민하·2022년 7월 27일
0

AWS

목록 보기
5/11
post-thumbnail

✅ 내용

  • DynamoDB 테이블 이름: lambda-apigateway
  • API gateway
    • endpoint: /dynamodbmanager
    • POST : 접속자의 IP 주소와 첫 방문일, 마지막 방문일을 저장/업데이트
    • GET : DynamoDB에 저장된 내역 조회
  • Postman API 명세서

✅ version 1.0

✔ lambda code

from datetime import datetime, timedelta, timezone

import boto3
import json
import socket
import random

def handler(event, context):
    
    dynamo = boto3.resource('dynamodb').Table('lambda-apigateway')
    KST    = timezone(timedelta(hours=+9), 'KST')
    ip     = socket.gethostbyname(socket.gethostname())
    response = dynamo.scan(TableName='lambda-apigateway')

    try:
        if bool(event) == True:
            for i in dynamo.scan(TableName='lambda-apigateway')["Items"]:
                if i["name"] == event["name"]:
                    dynamo.update_item(
                        Key = {"name" : event["name"]},
                        UpdateExpression = 'SET updated_at = :val1 , ip_address = :val2',
            
                        ExpressionAttributeValues={
                            ':val1': datetime.now(KST).strftime("%Y-%m-%d %H:%M:%S"),
                            ':val2': ip
                        }
                    )
                    return "UPDATE"
            
            dynamo.put_item(Item={
                "number" : random.randrange(1000000),
                "name" : event["name"],
                "created_at" : datetime.now(KST).strftime("%Y-%m-%d %H:%M:%S"),
                "updated_at" : datetime.now(KST).strftime("%Y-%m-%d %H:%M:%S"),
                "ip_address" : ip
            })
            
            return "CREATE"
        
        elif bool(event) == False:
            return "NO REQUEST"

    except:
        return response["Items"]

✔ GET 리소스 : 매핑 템플릿

  • content-type: application/json
  • 템플릿 생성: 메서드 요청 패스스루

✔ 문제점

  • GET이 되는 것처럼 보이지만, 에러가 발생해서 except문으로 넘어간 것일 뿐이다.
  • 매핑 템플릿
    • 설정을 안한 경우에는 "NO REQUEST"가 리턴됨(실패).
    • 설정을 한 경우에는 response["Items"]이 리턴됨(에러나면서성공).
    • 메서드 요청 패스스루로 하지 않고, 아무 변수를 넣어도 저장 내역이 리턴됐다(에러나면서성공).
  • 하나의 lambda 함수로 POST와 GET을 동시에 구현해야 함(현재 POST만 가능).

✅ version 2.0

✔ lambda code

from datetime import datetime, timedelta, timezone

import boto3
import json
import socket
import random

def handler(event, context):
    
    dynamo = boto3.resource('dynamodb').Table('lambda-apigateway')
    KST    = timezone(timedelta(hours=+9), 'KST')
    ip     = socket.gethostbyname(socket.gethostname())
    response = dynamo.scan(TableName='lambda-apigateway')

    try:
        if event["context"]["http-method"] == "GET" :
            return response["Items"]

    except:
        if bool(event) == True:
            for i in dynamo.scan(TableName='lambda-apigateway')["Items"]:
                if i["name"] == event["name"]:
                    dynamo.update_item(
                        Key = {"name" : event["name"]},
                        UpdateExpression = 'SET updated_at = :val1 , ip_address = :val2',
            
                        ExpressionAttributeValues={
                            ':val1': datetime.now(KST).strftime("%Y-%m-%d %H:%M:%S"),
                            ':val2': ip
                        }
                    )
                    return "UPDATE"
            
            dynamo.put_item(Item={
                "number" : random.randrange(1000000),
                "name" : event["name"],
                "created_at" : datetime.now(KST).strftime("%Y-%m-%d %H:%M:%S"),
                "updated_at" : datetime.now(KST).strftime("%Y-%m-%d %H:%M:%S"),
                "ip_address" : ip
            })
            
            return "CREATE"
        
        elif bool(event) == False:
            return "NO REQUEST"

✔ version 1.0 문제점 해결

  • GET 리소스 : 매핑 템플릿 : 메서드 요청 패스스루
    • AWS 공식 안내서
    • header에 매핑 템플릿이 정의되지 않은 경우에 이 패스스루 동작이 수행된다.
    • content > http-method 에서 http method 확인 가능.
    • event["context"]["http-method"] == "GET" 조건문 추가
  • 단, POST는 body에 json 데이터를 담아 요청하는 형식이기 때문에 이 방법을 사용할 수 없음
    • version 1.0 처럼 try 문에 POST에 대한 코드를 넣으면 error 발생
  • 그래서 except 문에 POST에 대한 코드를 넣어서 해결.
profile
backend developer 🐌

0개의 댓글