API Gateway는 lambda에서만 쓰이는 게 아니라 다른 서비스와 통신을 해야할 때 쓰이기 때문에 역할을 잘 알아두어야 한다.
클라이언트에서는 API 요청을 보낼 때 프록시를 써서 서버와 같은 url인 것 마냥 해결이 가능하지만 보통 서버에서 처리를 한다.
페이징 처리 람다로 하다가 머리 깨지는 줄... 안 그래도 해보지 않은 부분인데 그냥 구현해 보려니 힘들었다... 결국 답안 코드를 참고하면서 어찌어찌 채워보기는 했는데 AWS 내에서 수정하다 임포트 빠뜨리고 limit 띄어쓰기 빠뜨려서 한참 헤맸다... 로그로 다 알려주긴 해서 어디서 잘못됐는지 알기는 쉬웠다.
import json
import boto3
import pymysql
import math
from datetime import date
def get_secret():
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name="ap-northeast-2"
)
get_secret_value_response = client.get_secret_value(
SecretId='rds-secret-01'
)
token = get_secret_value_response['SecretString']
return eval(token)
def db_ops():
secrets = get_secret()
try:
connection = pymysql.connect(
host=secrets['host'],
user=secrets['username'],
password=secrets['password'],
db='mydb',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
except pymysql.MySQLError as e:
print("connection error!!")
return e
print("connection ok!!")
return connection
def lambda_handler(event, context):
print("lambda_handler is invoked")
try:
type = event['queryStringParameters']['type']
conn = db_ops()
cursor = conn.cursor()
if type == 'write':
if event['httpMethod'] == 'OPTIONS':
body = json.dumps({
"message": "success",
})
else:
today = date.today()
body = json.loads(event['body'])
cursor.execute("insert into bbs(title,content,regDate) value('" + body['title'] + "', '" + body['content'] + "', '" + today.strftime("%Y%m%d") + "')")
conn.commit()
body = json.dumps({
"message": "success",
})
elif type == 'list':
word = event['queryStringParameters']['word']
page = event['queryStringParameters']['page']
perPage = event['queryStringParameters']['perPage']
if page is None:
page = 1
if perPage is None:
perPage = 5
start = str((int(page)-1)*int(perPage))
if not word:
cursor.execute("select count(*) as count from bbs")
count = cursor.fetchone()
totalItems = int(count['count'])
totalPages = math.ceil(totalItems/int(perPage))
cursor.execute("select idx, title, regDate from bbs limit "+ start + "," + perPage)
result = cursor.fetchall()
else:
cursor.execute("select count(*) as count from bbs where (title like '%"+word+"%') or (content like '%"+word+"%')")
count = cursor.fetchone()
totalItems = int(count['count'])
totalPages = math.ceil(totalItems/int(perPage))
cursor.execute("select * from (select * from bbs where (title like '%" + word + "%') or (content like '%" + word + "%')) as A limit " + start + "," + perPage)
result = cursor.fetchall()
print(result)
body = json.dumps({
"result": "success",
"data": {
"contents" : result,
"pagination" : {"page":page, "perPage":perPage, "totalPages":totalPages, "totalItems":totalItems}
}
})
elif type == 'delete':
idx = event['queryStringParameters']['idx']
print(idx)
cursor.execute("delete from bbs where idx="+idx)
conn.commit()
body = json.dumps({
"result": "success",
})
elif type == 'deleteAll':
idxs = event['queryStringParameters']['idxs']
print(idxs)
cursor.execute("delete from bbs where idx in("+idxs+")")
conn.commit()
body = json.dumps({
"result": "success",
})
elif type == 'read':
idx = event['queryStringParameters']['idx']
cursor.execute("select * from bbs where idx="+idx)
bbs = cursor.fetchone()
body = json.dumps({
"result": "success",
"data": bbs
})
return {
"statusCode": 200,
#Cross Origin처리
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST,GET,DELETE'
},
"body": body,
}
except Exception as e:
print(e)
return {
"statusCode": 500,
#Cross Origin처리
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST,GET,DELETE'
},
"body": json.dumps({
"message": "fail",
}),
}
function getList(page) {
let word = $("#word").val();
$.ajax({
url: `${url}?type=list&page=${page}&perPage=${perPage}&word=${word}`,
method: "GET",
success: function (result) {
clear()
let titleList = result['data']['contents'];
let totalItems = result['data']['pagination']['totalItems'];
console.log(result['data']['pagination']['totalPages']);
let page = result['data']['pagination']['page'];
let start = totalItems - ((page - 1) * perPage);
console.log(start);
for (let i = 0; i < titleList.length; i++) {
let data = titleList[i]
$('#list').append(`<tr>
<th scope="row">${start - i}</th>
<td><input class="form-check-input" type="checkbox" name="idxs" value="${data['idx']}"></td>
<td><a href="#"token interpolation">${data['idx']})">${data['title']}</td>
<td>${data['regDate']}</td>
</tr>`);
}
setPage(page, result['data']['pagination']['totalPages'])
},
})
}
function setPerPage(setPerPage, target) {
perPage = setPerPage;
console.log(perPage);
for (let i = 0; i < $("#select_perPage").find('li').length; i++) {
$("#select_perPage").find('li:eq(' + i + ')').find('a').removeAttr("href");
}
$(target).attr("href", "#");
getList(1, perPage)
}
function setPage(page, totalPages) {
for (let i = 0; i < totalPages; i++) {
if (page == (i + 1)) {
$('#page').append(`<li class="page-item"><a class="page-link" href="#"token interpolation">${i + 1}, ${perPage})">${i + 1}</a></li>`);
} else {
$('#page').append(`<li class="page-item"><a class="page-link"token interpolation">${i + 1}, ${perPage})">${i + 1}</a></li>`);
}
}
}
html 붙여주는 거는 좀 더 봐야할 듯하다. 스프링으로는 페이징하기가 수월하다고 하니 다행이다^^;;
검색기능
검색창 입력한거 가져오고 html 붙이기
입력값 가져오기
검사하고 입력하지 않았으면 focus
GET 넣고
for문마다 itemDto 꺼내서 html 만들고 붙이기
파라미터로 넣어줄 때 자바스크립트는 알아서 json형태로 바꾼다. 그래서 넣어줄 때 문자열화시켰더라도, 받은 뒤에 또 처리를 해줘야 한다.
SAVE 💾
이번 주말 뜻하지 않게 바빠서 공부할 시간이 없었다... 이틀 쉬고 다시 보니까 왜 이렇게 낯설은지ㅎㅎ... 3계층 부분 복습해야겠다. js랑 html 쪽은 이전에도 했던 거라서 그나마 괜찮은 것 같은데 자료 뽑아내는 게 어떤 형태인지 매번 확인하면서 진행하질 않았어서 조금 헷갈렸다.
유료 버전 라이센스 코드가 적용되는지 모르고 무료 버전 쓰다가 오늘 옮기려고 하니 세팅 과정에서 오류가 발생해서 그거 해결하느라 시간 다 썼다... 아까워ㅜㅜ
참고
파이썬 쿼리
js 페이징
js 페이징
람다 핸들러(py)
this.href vs $(this).attr('href')
CORS
이틀 공부를 아예 놓아버리면 월요일에 정말 낯설고 새롭죠 ㅋㅋㅋ 조금씩이라도 맛보는 것이 좋아요 ㅎㅎ 스프링도 꾸준히 공부해주시는 게 넘 좋아요 홧팅