๐ฅ TIL - Day 44
๐ Flask API ์๋ฒ EB์์ Lambda๋ก ์ด์ฌ๊ฐ๊ธฐ
์ผ๋จ ์ค๋์ ์ธ๋ฑ์ค ํ์ด์ง์์ ์ธ๋ถ API๋ฅผ ํธ์ถํด์ ๋ฆฌ์คํ ํ๋ API๋ฅผ Lambda๋ก ์ฎ๊ธฐ๋ ์์ ์ ํ๋ค.
aws sam
์ ์ฌ์ฉํ๋๋ฐ sam
์ ๋ํด ๊ฐ๋จํ๊ฒ ์์๋ณด์.
SAM (Serverless Application Model)
sam์ ์๋ฒ๋ฆฌ์ค ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณด๋ค ์ฝ๊ฒ ๊ด๋ฆฌํ ์ ์๊ฒ AWS๊ฐ ์ ๊ณตํด์ฃผ๋ ํ๋ ์์ํฌ์ด๋ค. sam์ ์ฌ์ฉํ๊ธฐ ์ ์ ์ฐ๋ฆฌ๋ ์ง์ API ์ฝ๋๋ฅผ ์์ฑํ๊ณ ํ์ํ ๋ชจ๋์ ํจ๊ป ์์ถํด์ ๋ฏธ๋ฆฌ ์์ฑํ Lambda ํจ์์ ์ฌ๋ ค์คฌ์๋ค.
SAM์ ์ฌ์ฉํ๋ฉด ์ฝ๋ ์์ค์์ ์ด๋ฐ ์ผ๋ จ์ ์์ ์ ๋ํ ์๋ํ ์ค์ ์ ํ ์ ์๋ค. (IoC, Infrastructure as Code)
์.. ๊ทผ๋ฐ ์์งํ ๊ฐ๋จํ API๋ ๊ทธ๋ฅ ์ง์ ์ฌ๋ฆฌ๋ ๊ฒ ๋ ํธํ์ง ์์๊น? ๋ผ๋ ์๊ฐ์ด ๋ค๊ธด ํ๋ค.. ใ
ํ์ง๋ง ์ฝ๋๋ก ์ค์ ํ ์ ์๋ค๋ ๊ฒ์ ์ค์ ์์ฒด๋ฅผ ์ฌ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ด๋ ๊ทธ๋ฅ ์ฐ๋๊ฒ ๋์ค์ ์ํด์ ๋ ์ข์ ๊ฒ ๊ฐ๋ค. ์ ์จ๋ณด์.
sam
์ ์ฌ์ฉํ ๋ ค๋ฉด aws-cli
์ sam-cli
๊ฐ ์ค์น๋์ด์ผ ํ๋ค.
macos ๊ธฐ์ค
brew install awscli
brew tap aws/tap
brew install aws-sam-cli
๐ ํ๋ก์ ํธ ์์ฑ
์ด์ sam
ํ๋ ์์ํฌ ํ๋ก์ ํธ๋ฅผ ํ๋ ์์ฑํ๋ค.
sam init
์ด๋ฐ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๊ฐ ๋ณด์ผ ๊ฒ์ด๋ค.
aws sam์ ์ค์ ํ์ผ์ ํตํด ์๋ฒ๋ฆฌ์ค ์ ํ๋ฆฌ์ผ์ด์
์ ๊ด๋ฆฌํ๋ค๊ณ ํ๋ค.
๊ทธ ์ค์ ํ์ผ์ด template.yaml
์ด๋ค.
์ผ๋จ ์์ธํ ์ค์ ์ ์ฐจ์ฐจ ํ์ํ ๋ ์ฐพ์๋ณด๋ ๊ฑธ๋ก ํ๊ณ ๋ฐฐํฌ์ ๋ฐ๋์ ํ์ํ ๋ถ๋ถ๋ง ์ดํด๋ณด์. (์ฃผ์ ์ฃผ์)
Resources:
# HelloWorld API
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/ # API๊ฐ ์๋ ๋๋ ํ ๋ฆฌ๋ช
Handler: app.lambda_handler # ํธ๋ค๋ฌ ํจ์๋ช
(API์ ๊ทผ์ ์คํ๋ ํจ์)
Runtime: python3.8
Architectures:
- x86_64
Events:
HelloWorld:
Type: Api
# APIGateway์๋ํฌ์ธํธ/hello <-- ์ด๊ฒ API์ ์๋ํฌ์ธํธ๊ฐ ๋๋ ๊ฒ
Properties: # API Gateway์ ๋ํ ์ค์
Path: /hello # HTTP ๊ฒฝ๋ก
Method: get # HTTP Method
๊ทธ๋ผ ์ด์ API์ ๋ํ ์ค์ ์ ํด์ฃผ์.
์์ง ์ฐ์ต๋จ๊ณ๋ผ VPC ์ค์ ์ ํด์ฃผ์ง ์์๋ค.
TodayLawListFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: tl_list/
Handler: app.lambda_handler
Runtime: python3.8
Architectures:
- x86_64
Events:
TodayLawList:
Type: Api
Properties:
Path: /laws
Method: get
API ์ฝ๋
event
๊ฐ์ฒด๋ก ์ฟผ๋ฆฌ์คํธ๋ง์ ๋ฐ์ ๋ null ์ฒดํฌ๊ฐ ํ๋ค๋ค..
์ง์ if๋ฌธ์ผ๋ก null์ฒดํฌ๋ฅผ ํ๋ ค๊ณ queryStringParameters
๋ก ์ ๊ทผํ ์๊ฐ ๋ ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค.
๊ทธ๋์ Front ๋จ์์ ๋น ๊ฐ์ ๋์ ธ์ฃผ๋ ๊ฑธ๋ก ์์ ํ๋ค.
์ด๋ฐ์์ผ๋ก ใ
ใ
$.ajax({
type: "GET",
url: `${api_url}/laws?offset=${offset}&query=&proposer=&condition=๋ฒ์๋ช
`,
๋ณ๋ก๋ค..
def lambda_handler(event, context):
try:
query = event['queryStringParameters']['query']
proposer_name = event['queryStringParameters']['proposer']
condition = event['queryStringParameters']['condition']
pIndex = event['queryStringParameters']['offset']
#== ๊ฒ์์กฐ๊ฑด์ด ์๋ ๊ฒฝ์ฐ ==#
if query is None and condition is None:
data = requests.get(
f'https://open.assembly.go.kr/portal/openapi/nzmimeepazxkubdpn?Key={api_key}&Type={type}&AGE={age}&pIndex={pIndex}&pSize=10')
#== ๋ฒ์๋ช
์ผ๋ก ๊ฒ์ ==#
elif condition == '๋ฒ์๋ช
':
url = f'https://open.assembly.go.kr/portal/openapi/nzmimeepazxkubdpn?Key={api_key}&Type={type}&AGE={age}&BILL_NAME={query}&pIndex={pIndex}&pSize=10'
query = encode_querystring(url)
data = requests.get('https://open.assembly.go.kr/portal/openapi/nzmimeepazxkubdpn?' + query)
#== ๋ฒ์๋ฐ์ ์ ์์๋ช
์ผ๋ก ๊ฒ์==#
elif condition == '์ ์์':
url = f'https://open.assembly.go.kr/portal/openapi/nzmimeepazxkubdpn?Key={api_key}&Type={type}&AGE={age}&PROPOSER={proposer_name}&pIndex={pIndex}&pSize=10'
query = encode_querystring(url)
data = requests.get('https://open.assembly.go.kr/portal/openapi/nzmimeepazxkubdpn?' + query)
data = data.json()
total_count = data['nzmimeepazxkubdpn'][0]['head'][0]['list_total_count']
data = data['nzmimeepazxkubdpn'][1]['row']
response = []
response.append({'total_count':total_count})
for d in data:
names = d['PUBL_PROPOSER']
names = get_other_proposer(names)
response.append({
'id':d['BILL_ID'],
'title':d['BILL_NAME'], # ๋ฒ์์ ๋ชฉ
'proposer_name':d['RST_PROPOSER'], # ๋ํ์ ์์
'proposer_names':names, # ๋ํ์ ์์ ์ธ ์ ์์
'date':d['PROPOSE_DT'], # ๋ฐ์ ๋ ์ง
'url':d['DETAIL_LINK'], # ์์ธ๋ด์ฉ ํฌ๋กค๋ง link
'total_count':total_count
})
body = json.dumps(response)
return {
"statusCode": 200,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,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': 'GET'
},
"body": json.dumps({
"message": "fail",
}),
}
๊ทธ๋ผ ์ค๋น๋ ๋๋ฌ์ผ๋ ๋น๋ / ๋ฐฐํฌ๋ฅผ ํด์ค๋ค.
sam build
sam deploy [--guided]
HelloWorld API
๊น์ง ์ด 2๊ฐ Lambda ํจ์๊ฐ ์์ฑ๋๋ค.
Lambda ํจ์์ ํธ๋ฆฌ๊ฑฐ์ ์ค์ ๋ API Gateway๋ฅผ ๋ณด๋ฉด ์ฐ๋ฆฌ๊ฐ ์ค์ ํ ๋๋ก ์๋ํฌ์ธํธ๊ฐ ์ค์ ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ก์ปฌ์์ ๋ฆฌ์คํ
API ํ
์คํธ!
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฅ TIL - Day 44), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@dhk22/TIL-Day-44์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค