[AWS]Serverless API(一)

GaryLin
Gary的程式學習紀錄簿
6 min readAug 4, 2023

用API Gateway + Lambda + DynamoDB來建立API

由於用EC2+RDS的成本對於一般想建立網站的人來說看到一年要上萬元的花費都會望之卻步(不要問我為什麼一家公司連一年不到10萬的網站預算都拿不出來…),所以相對的隨需計費的API Gateway + Lambda + DynamoDB的架構對於他們就很有吸引力,沒有基礎成本,有人使用時才會計費的方式會讓他們覺得很便宜,雖然寫程式的你知我知大家都知道,那些服務在一直作用的情況下累積的費用其實比租用EC2還高,DynamoDB在一些情況也是無法取代RDBMS,而且使用後也相對被雲綁架,不過對於使用人數少的小型網站的確是很有吸引力,所以開始來學習一下基於AWS服務的後端Serverless架構

本次一開始先建立簡單的API Gateway + Lambda + DynamoDB,Lambda使用的語言是python,因為經研究後感覺Lambda對於直譯式語言會比較友善,NodeJS和python我比較熟悉python所以就選他了,第一次使用建議參考AWS官方文件手動建立一次基本架構,然後再調整

接下來來基於上面內容繼續嘗試,把Lambda中的python部分加上FastAPI,來讓程式更加容易閱讀,也可以將Rest都導到同一個Lambda下

首先來建立Layer,這就是libery的部分,安裝的第三方套件都是放到這邊,首先先建立一個requirements.txt,內容就先放這次要用到的2個套件

fastapi==0.99.0
mangum==0.11.0

然後新增一個python資料夾,執行下面指令將套件安裝進去

pip install --target ./python -r requirements.txt

然後將資料夾打包準備上傳

zip -r dependencies.zip ./python

到Lambda頁面新增Layer,這邊我們就先上傳剛剛打包的zip檔,執行時間就選擇對應的python版本

完成後就可以取得版本arn,這個位置之後會用到

接下來我們來建立一個簡單的RestAPI,首先照之前建立lambda-apigateway方式來建立一個user給這個api用

然後我們建立一個UserRest.py,裡面是一個對user操作的簡單RestAPI

from fastapi import FastAPI
import boto3
import uuid
from mangum import Mangum

app = FastAPI()

# define the DynamoDB table that Lambda will connect to
tableName = "user"
# create the DynamoDB resource
userdb = boto3.resource('dynamodb').Table(tableName)

def get_user_by_id(member_id: str):
query = {'id': member_id}
user = userdb.get_item(Key=query)
return user.get('Item')


@app.get('/member')
def get_data():
return userdb.scan().get('Items')

@app.get('/member/{member_id}')
def get_data_by_member_id(member_id: str):

return get_user_by_id(member_id)

@app.post('/member')
async def insert_user(payload: dict):
member_id = str(uuid.uuid1())
payload['id'] = member_id
userdb.put_item(Item=payload)

return get_user_by_id(member_id)

@app.patch('/member/{member_id}')
async def insert_user(member_id: str, payload: dict):
item = get_user_by_id(member_id)
for k, v in payload.items():
item[k] = v
userdb.put_item(Item=item)

return item

@app.delete('/member/{member_id}')
async def insert_user(member_id: str):
query = {'id': member_id}

return userdb.delete_item(Key=query)

handler = Mangum(app) # Special Handler For AWS Lambda

然後在上傳的指令裡加入下面指令,arn後面記得改成剛剛建立的layer

--layers arn:aws:lambda:ap-southeast-1:1111111111:layer:Base:1

打包丟上去Lambda部分就完成了,接下來在api gateway新增member,階層構造如下圖

ANY部分記得要勾選使用 Lambda 代理整合

然後就可以測試了

先弄出一個最基本的API結構出來,後面還要學習要怎麼整合Cognito進行身份驗證,之後再架構一下整個的服務和程式架構,不知道哪邊有前輩的架構可以參考(思),不然整個自己從頭架構感覺就像重新造輪子(攤手)

下一次更新應該是整合Cognito完成有時間紀錄時吧…

--

--