ทำ API ง่ายๆ ด้วย AWS Lambda และ Python
ทำ API ง่ายๆ ด้วย AWS Lambda และ Python: เริ่มต้นยังไงให้ไม่ปวดหัว!
สวัสดีทุกคน! วันนี้มาคุยเรื่อง Lambda กันหน่อย คือถ้าใครอยากทำ API เล็กๆ หรือ microservice แบบไม่ต้องปวดหัวเรื่องเซิร์ฟเวอร์อะนะ Lambda มันตอบโจทย์เลยล่ะ
Lambda มันดียังไง?
จริงๆ มันก็คือ serverless computing ตัวนึงแหละ แปลว่าเราไม่ต้องไปยุ่งกับเรื่อง Provisioning Server, Scaling, หรือ Patching OS เลย แค่เขียนโค้ดโยนขึ้นไป ที่เหลือ AWS จัดการให้หมด เจ๋งปะ? ข้อดีอีกอย่างคือมันคิดตังค์ตามที่เราใช้งานจริงนะ ไม่ได้เปิดทิ้งไว้แล้วคิดตลอดเวลา เหมาะกับงานที่ไม่ต้องรันตลอดเวลาอย่างพวก Webhook, Cron Job, หรือ Backend สำหรับ Mobile App อะไรพวกนี้
แต่ก็ใช่ว่าจะดีไปหมดนะ บางทีก็มีเรื่อง cold start มั่งล่ะ หรือจัดการ dependencies ที่ต้องแพ็คเองก็แอบงงๆ นิดหน่อย
เตรียมตัวก่อนลุย
ก่อนจะเริ่มก็ต้องมี AWS Account ก่อนนะ แล้วก็ติดตั้ง AWS CLI ให้เรียบร้อย อันนี้สำคัญมาก เพราะเราจะใช้มัน deploy โค้ดไง
# ถ้ายังไม่มี AWS CLI
# สำหรับ Linux/macOS
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# หรือสำหรับ Windows ก็ไปดูวิธีติดตั้งใน docs ของ AWS ได้เลยนะ
อย่าลืม aws configure ด้วยนะ เพื่อตั้งค่า Access Key, Secret Key ให้ CLI มันใช้งานได้
โค้ด Lambda ง่ายๆ
มาลองเขียนโค้ด Python แบบเบสิกสุดๆ กันก่อน จะเอาไว้รับ request แล้วตอบกลับไปแค่นั้นแหละ
สร้างไฟล์ชื่อ lambda_function.py
import json
def lambda_handler(event, context):
"""
ฟังก์ชัน Lambda หลักของเรา. เป็น entry point ของโค้ด
event: ข้อมูลที่ Lambda รับมา (มาจาก API Gateway หรือแหล่งอื่นๆ).
context: ข้อมูลเกี่ยวกับ runtime ของ Lambda.
"""
print(f"Got an event: {json.dumps(event, indent=2)}")
# ลองเช็คว่ามี query parameters มามั้ย
name = "World"
if 'queryStringParameters' in event and event['queryStringParameters'] is not None:
if 'name' in event['queryStringParameters']:
name = event['queryStringParameters']['name']
# ตอบกลับเป็น JSON
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json'
},
'body': json.dumps({
'message': f'Hello, {name} from Lambda!'
})
}
# ตัวอย่างสำหรับรันใน local (เผื่ออยากลองก่อน deploy)
if __name__ == '__main__':
# จำลอง event ที่มาจาก API Gateway
mock_event = {
"queryStringParameters": {
"name": "Cii3"
}
}
mock_context = {}
response = lambda_handler(mock_event, mock_context)
print("--- Local Test Response ---")
print(json.dumps(response, indent=2))
โค้ดนี้ง่ายๆ เลย คือรับ event เข้ามา แล้วก็ดึง name ออกมาจาก queryStringParameters ถ้ามีนะ แล้วก็ตอบกลับไปเป็น JSON
Deploy กันเถอะ!
ขั้นตอนการ Deploy นี่แหละที่บางคนอาจจะงงๆ คือเราต้อง Zip ไฟล์โค้ดเราก่อนนะ
zip my_lambda_function.zip lambda_function.py
จากนั้นก็ใช้ AWS CLI เพื่อสร้างฟังก์ชัน Lambda ขึ้นมา
aws lambda create-function \
--function-name myPythonApiFunction \
--runtime python3.9 \
--zip-file fileb://my_lambda_function.zip \
--handler lambda_function.lambda_handler \
--role arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/lambda-execution-role \
--region YOUR_AWS_REGION # เช่น ap-southeast-1
สำคัญมาก: * --function-name: ตั้งชื่อให้ฟังก์ชันเรา * --runtime: ใช้ Python 3.9 (หรือเวอร์ชันอื่นที่ต้องการ) * --zip-file: ชี้ไปที่ไฟล์ .zip ที่เราสร้างไว้ * --handler: บอก Lambda ว่าไฟล์ไหนคือโค้ดหลัก และฟังก์ชันไหนเป็น entry point (ชื่อไฟล์.ชื่อฟังก์ชัน) ในตัวอย่างคือ lambda_function.lambda_handler * --role: อันนี้แหละตัวสำคัญ ต้องมี IAM Role ที่มีสิทธิ์ให้ Lambda รันได้และเข้าถึง CloudWatch Logs ได้นะ ปกติจะชื่อประมาณ lambda_basic_execution หรือเราสร้างเองก็ได้ โดยให้มี AWSLambdaBasicExecutionRole policy
**ข้อผิดพลาดที่เคยเจอ (และโคตรบ่อย):** ถ้า Role ที่ให้ไปไม่มีสิทธิ์ที่จำเป็น, Lambda มันจะรันไม่ได้เลยครับ หรือไม่ก็ error ตอนพยายามเขียน Log ลง CloudWatch. แบบนี้คือเราต้องไปสร้าง Role ใน IAM Console เอง แล้วก็แนบ Policy `AWSLambdaBasicExecutionRole` เข้าไป หรือถ้าต้องเข้าถึง S3 หรือ DynamoDB ก็ต้องเพิ่ม Policy เหล่านั้นเข้าไปด้วย ไม่งั้นจะเจอ `AccessDeniedException` เวลา Lambda พยายามทำอะไรที่เกินสิทธิ์! อีกอย่างถ้าคุณมี external libraries ที่ไม่ได้มากับ Python standard library แล้วลืมรวมไว้ใน zip ไฟล์ ก็จะเจอ `ModuleNotFoundError` ด้วยนะ ต้อง `pip install -t . <package_name>` แล้วค่อย zip ทั้งหมดไปเลย
--region: เลือก Region ที่ใกล้เราที่สุด เช่นap-southeast-1(สิงคโปร์)
ทดสอบฟังก์ชัน
พอ Deploy เสร็จแล้ว เราก็ลอง Invoke มันดูใน AWS Console ก็ได้ หรือใช้ CLI ก็ได้
aws lambda invoke \
--function-name myPythonApiFunction \
--payload '{"queryStringParameters": {"name": "Test"}}' \
response.json
คำสั่งนี้จะส่ง payload เข้าไป แล้วผลลัพธ์จะถูกบันทึกใน response.json ลองเปิดดูได้เลย
ถ้าอยากให้มันเป็น API จริงๆ จังๆ ก็ต้องไปผูกกับ API Gateway อีกทีนะ ซึ่งอันนั้นก็อีกเรื่องนึง ไว้มีโอกาสจะมาเล่าให้ฟัง
สรุปส่งท้าย
Lambda เนี่ยมันโคตรมีประโยชน์เลย สำหรับงานที่ไม่ซับซ้อนมาก หรือต้องการ scale แบบไม่ต้องคิดเยอะ เหมาะมากเลยกับการทำ Microservices หรือ Backend เล็กๆ ของเรา
ส่วนตัวนะ ผมว่า Lambda เหมาะสุดตอนที่เราไม่อยากดูแลเซิร์ฟเวอร์เลย แล้วก็งานที่ไม่ได้มี Traffic ตลอดเวลา แต่ถ้ารันตลอดเวลาจริงๆ บางที EC2 อาจจะคุ้มกว่าในระยะยาวนะ ลองชั่งน้ำหนักดู
หวังว่าบทความนี้จะพอเป็นแนวทางให้คนที่สนใจได้ลองเล่น Lambda ดูนะครับ ไม่ได้ยากอย่างที่คิดหรอก แต่แรกๆ อาจจะงงเรื่อง Role กับ Dependencies หน่อย สู้ๆ!