Lambdaã§é¢æ°ã¯äœããããªã®ã«ãã©ãŠã¶ããåŒã¹ãURLãç¡ãã ãã®èšäºã¯AWSå匷ã·ãªãŒãºã®15æ¬ç®ã§ã颿°ããäžçäžããåŒã¹ãURLãã«å€ããAPI Gatewayãæ±ããŸããèªã¿çµãããšãåå¿è ãèžã2ã€ã®çç¶ãèªåã§åãåããããŸãã1ã€ç®ã¯ããããã€ããããšããã The REST API doesn't contain any methods ãšèšãããŠæ¢ãŸããã2ã€ç®ã¯ãèšå®ãå€ããã®ã«ãURLãå©ããšå€ãåãã®ãŸãŸããã©ã¡ãã仿¥ãã¢ãã¯AWSã§ãããšèžãã§ãæ¢ãŸãå Žæã確ãããŸããã
察象èªè ã¯ãAWSãããããåŠã¶äººãšãã·ãªãŒãºã1æ¬ç®ããèªãã§ãã人ã§ããã¢ã«ãŠã³ããç¡ããŠã倧äžå€«ã§ãã³ãŒãã¯å šéšæå ã®Pythonã ãã§åããŸãã
[toc]
API Gatewayãšã¯äœã
API Gatewayã¯ãã¬ã¹ãã©ã³ã®æ³šæã«ãŠã³ã¿ãŒã§ãã
ååãŸã§ã«äœã£ãLambdaã¯ãåšæ¿ã®ã³ãã¯ãããã§ãããæç(åŠç)ã¯ã§ããããã©ãã客ãã(å©çšè )ãåšæ¿ã«çŽæ¥å ¥ããããã«ã¯ãããŸããã誰ã§ãå ¥ãããå·èµåº«ãæŒãããŸããããã§åºã®å ¥å£ã«æ³šæã«ãŠã³ã¿ãŒã眮ããã¡ãã¥ãŒã«èŒã£ãŠããæ³šæã ããåããŠãåšæ¿ã«éãããã®ä¿ãAPI Gatewayã§ãã
AWSã®èšèã§èšãçŽããšããã€ã³ã¿ãŒãããããã®HTTPãªã¯ãšã¹ããåãåããæ±ºããããã«ãŒã«ã«åããã®ã ããLambdaãªã©ã®äžèº«ã«æž¡ããçµæãè¿ãçé¢ãã§ããçé¢ãªã®ã§ãURLã®çºè¡ã泚æã®éžå¥ãæ··ã¿ããããšãã®å ¥å Žå¶éãŸã§ãããåãæã¡ãŸãã
äœã«äœ¿ãã
äžçªããããäœ¿ãæ¹ã¯ãLambda颿°ã«å ¬éURLãä»ããããšã§ãã
- ã¹ããã¢ããªã®ããã¯ãšã³ãããGET /users ãªãäžèЧãPOST /users ãªãç»é²ãã®ããã«URLãšåŠçã察å¿ããã
- Webãµã€ãã®åãåãããã©ãŒã ã®éä¿¡å
- å€éšãµãŒãã¹ããã®Webhook(éç¥)ã®åãå£
ã·ãªãŒãº5æ¬ç®ã®Lambdaåã§ã颿°ãäœã£ãŠæå
ãã invoke ã§åŒã³ãŸãããããã¯AWSã®å
åŽããã®åŒã³åºãã§ããå€ã®äžçãã€ãŸããã©ãŠã¶ãã¹ããããåŒã¶ã«ã¯ãçé¢ãèŠããŸãããã®çé¢ãAPI Gatewayã§ãã
æ¢åºãµãŒãã¹ãšã®éã
ã·ãªãŒãºã§äŒŒãé¡ã¶ããå¢ããŠããã®ã§ãäœçœ®é¢ä¿ãæŽçããŸãã
| ãµãŒãã¹ | åœ¹å² | äŸãããš |
|---|---|---|
| Route 53(13æ¬ç®) | ååãIPã¢ãã¬ã¹ã«å€æãã | é»è©±åž³ |
| CloudFront(14æ¬ç®) | ã³ã³ãã³ããè¿ãããéãé ã | è¿æã®ã³ã³ãã |
| API Gateway(ä»å) | HTTPãªã¯ãšã¹ããéžå¥ããŠäžèº«ã«æž¡ã | 泚æã«ãŠã³ã¿ãŒ |
| Lambda(5æ¬ç®) | å®éã®åŠçããã | åšæ¿ã®ã³ã㯠|
Route 53ã¯å Žæèª¿ã¹ãCloudFrontã¯é éã§ãã©ã¡ããåŠçã¯ããŸãããåŠçãžã®å ¥å£ã¯API GatewayãåããŠã§ãã
ä»AWSã®å°å³ã®ã©ãã«ããã
å š20æ¬ã®å°å³ã§èšããšãéšåç·š12æ¬ãçµãããå ¬éç·šã®3æ¬ç®ã§ããRoute 53ã§ååãæã¡ãCloudFrontã§é ãä»çµã¿ãæã¡ãŸãããä»åã®API Gatewayã§ãåŠçãåãä»ããçé¢ããä»ããŸããå ¬éç·šã®æ®ãã¯ECSã§ããã®å ã«éçšç·šãæ§ããŠããŸãã
ä»ã¯ããã ãåããã°OK
èŠããèšèã3ã€ã«çµããŸãã
-
ãªãœãŒã¹ ⊠URLã®ãã¹ã®ããšã
/helloã/usersãšãããæ£ããäœã - ã¡ãœãã ⊠æ£ããšã®å仿¹æ³ãGET(èŠã)ãPOST(éã)ãªã©
- ããã〠⊠äœã£ãèšå®ãäžã«åºãæäœãããããããŸã§1æåãå ¬éãããªã
éã«ãçµ±åã¿ã€ãã®çš®é¡(MOCKãAWS_PROXYãªã©)ããªãŒãœã©ã€ã¶ãŒã䜿çšéãã©ã³ã¯åŸåãã§ãããæåã®1æ¬ãéãã®ã«èŠãã®ã¯äžã®3ã€ã ãã§ãã
ä»çµã¿ã®èŠç¹
API Gatewayã®äžèº«ã¯4éå±€ã®çµã¿ç«ãŠã©ã€ã³ã§ãã
-
ãªãœãŒã¹: ãã¹
/helloãäœã - ã¡ãœãã: ãã®ãã¹ã«GETãçãã
- çµ±å: ã¡ãœããã®å ãLambdaãªã©ã«é ç·ãã
- ãããã€: ã¹ããŒãž(prod ã dev)ãšããååãä»ããŠå ¬éãã
ã§ããããURLã¯æ¬¡ã®åœ¢ã§ãã
https://APIçªå·.execute-api.ap-northeast-1.amazonaws.com/prod/hello
~~~~ ~~~~~
ã¹ããŒãž ãªãœãŒã¹
1ã3ããããäœã蟌ãã§ãã4ã®ãããã€ããããŸã§å€ããã¯äœãèŠããŸãããLambdaã¯äœã£ãç¬éãã invoke ã§ããŸããããAPI Gatewayã«ãã®æèŠãæã¡èŸŒããš404ãæ¢ãåãããšã«ãªããŸãã
äœ¿ãæ¹(æå°ã³ãŒã)
ãã€ãéããå®éã®AWSã§ã¯ãªãmoto(AWSã®ãã£ãããã)ã§åãããŸãããéã¯äžåããããŸããã
pip install boto3 moto
äœãâå ¬éããâ確ããããã®æå°ã³ãŒãã§ãã
import boto3
from moto import mock_aws
@mock_aws
def main():
apigw = boto3.client("apigateway", region_name="ap-northeast-1")
# 1. APIæ¬äœãäœã
api = apigw.create_rest_api(name="hello-api")
api_id = api["id"]
# ã«ãŒã(/)ã®IDã調ã¹ã(pathã"/"ã®ãã®ãæ¢ã)
items = apigw.get_resources(restApiId=api_id)["items"]
root_id = [r for r in items if r["path"] == "/"][0]["id"]
# 2. ãªãœãŒã¹ /hello ãäœã
res = apigw.create_resource(restApiId=api_id, parentId=root_id, pathPart="hello")
# 3. GETã¡ãœãããçãã
apigw.put_method(restApiId=api_id, resourceId=res["id"],
httpMethod="GET", authorizationType="NONE")
apigw.put_method_response(restApiId=api_id, resourceId=res["id"],
httpMethod="GET", statusCode="200")
# 4. çµ±åã匵ã(ä»åã¯åºå®å¿çã®MOCK)
apigw.put_integration(restApiId=api_id, resourceId=res["id"], httpMethod="GET",
type="MOCK",
requestTemplates={"application/json": '{"statusCode": 200}'})
apigw.put_integration_response(restApiId=api_id, resourceId=res["id"],
httpMethod="GET", statusCode="200",
responseTemplates={"application/json": '{"message": "hello"}'})
# 5. ãããã€(ããã§åããŠäžã«åºã)
apigw.create_deployment(restApiId=api_id, stageName="prod")
print(f"åŒã³åºãURL: https://{api_id}.execute-api.ap-northeast-1.amazonaws.com/prod/hello")
main()
å®è¡çµæã§ãã
åŒã³åºãURL: https://rsgosywmky.execute-api.ap-northeast-1.amazonaws.com/prod/hello
rsgosywmky ã®éšåã¯APIãäœããã³ã«å€ããã©ã³ãã ãªIDã§ããããã¯motoãçºè¡ããåœç©ã®IDãªã®ã§ããã®URLèªäœããã©ãŠã¶ã«è²Œã£ãŠãç¹ãããŸãããå®éã®AWSã§åãã³ãŒããæµããšãæ¬ç©ã®IDã§åã圢ã®URLãçºè¡ããã貌ããš {"message": "hello"} ãè¿ããŸãã
ä»ããªããäœã£ããã®
ããŸæå ã«ããã®ã¯ããã ãã§ãã
- hello-api(APIæ¬äœ)
- GET /hello(ã¡ãœãã1æ¬)
- MOCKçµ±å(åºå®ã®è¿äºãè¿ãé ç·)
- prodã¹ããŒãž(å ¬éäž)
ä»åã¯é
ç·å
ãMOCK(åºå®å¿ç)ã«ããŸããããããã type="AWS_PROXY" ã«ããŠLambdaã®ARNãæž¡ããšã5æ¬ç®ã§äœã£ã颿°ããã®ãŸãŸå¿çãè¿ãããã«ãªããŸãã
1ãæã ãå€ããŠã¿ã
ã¹ããŒãžåãå€ããŠããã1ã€å ¬éããŠã¿ãŸãã
apigw.create_deployment(restApiId=api_id, stageName="dev")
ããã ãã§ .../dev/hello ãšããURLãå¢ããŸããæ¬çªã¯ prodãå®éšã¯ dev ãšåããŠãããšãdevã§å£ããŠãprodã«ã¯åœ±é¿ããŸããã
å®éã«å©ããšæ¢ãŸããšãã
ãããããæ¬ç·šã§ããå®éšã¹ã¯ãªããã«ã¯ããšã©ãŒ1ãããããšã©ãŒ6ããŸã§èŠåºãã6ã€çšæããŠãé ã«èžãã§ãããŸãããå ã«çœç¶ãããšã6ã€ã®ãã¡2ã€(ãšã©ãŒ3ãšãšã©ãŒ4)ã¯æ¢ãŸããŸããã§ããããšã©ãŒã«ãªãã¯ãã®æäœãæåã§è¿ã£ãŠããŠãèŠåºãã ããããšã©ãŒãã®ãŸãŸæ®ã£ãããã®2ã€ã¯ç¯ã®æåŸã«åããŸããããšãšã©ãŒ6(å逿žã¿APIãããäžåºŠèŠã)ã¯ãšã©ãŒ2ãšåãæèšãè¿ã£ãã ããªã®ã§å²æããŠãèŒããã®ã¯æ¢ãŸã£ã3ã€ãšæ¢ãŸããªãã£ã2ã€ã§ãã
ãšã©ãŒ1: ã¡ãœããã1ã€ãç¡ããŸãŸãããã€
åºãäœã£ãçŽåŸãã¡ãã¥ãŒã眮ãåã«éåºããããšãããšæ¢ãŸããŸãã
ClientError: BadRequestException
The REST API doesn't contain any methods
create_rest_api ã§è¿ã£ãŠããã®ã¯APIã®IDã ãã§ããã®æç¹ã§ã¯äžèº«ã空ã§ããã¡ãœããã1åäœã£ãŠããåã create_deployment ãæãçŽãããéããŸããã
ãšã©ãŒ2: ååšããªãAPI IDãèŠã
ClientError: NotFoundException
Invalid Rest API Id specified
çŽ çŽãªãšã©ãŒã§ããIDã®ã¿ã€ããã¹ã§ããããåºãŸãã1ã€è£è¶³ãããšããã®æèšã¯motoã®ãã®ã§ãå®éã®AWSã¯ãInvalid API identifier specified 123456789012:abc123xyzãã®ããã«ã¢ã«ãŠã³ãIDãä»ãã圢åŒã§è¿ããŠããŸãã
ãšã©ãŒ5: ã¹ããŒãžãæ®ã£ããŸãŸãããã€æ¬äœãæ¶ã
ClientError: BadRequestException
Active stages pointing to this deployment must be moved or deleted
ããã®ãããã€ãæããŠããã¹ããŒãžãæ®ã£ãŠããããšæãããŸããæ¶ãé çªã¯ã¹ããŒãžâãããã€âAPIæ¬äœãéé ã§æãããäžã®ãšã©ãŒã§æ¢ãŸããé çªãå®ã£ããå šéšæ¶ããŸããã
åé€å®äº: ã¹ããŒãžâãããã€âAPIæ¬äœã®é ã§æå
æ¢ãŸããªãã£ããšã©ãŒ3ãšãšã©ãŒ4(motoã®åçŸæŒã)
ãšã©ãŒ3ãšãšã©ãŒ4ã¯æåãè¿ã£ãŠããŸãããmoto(æå ã¯5.2.3)ã§ã¯éãã®ã«ãå®éã®AWSã§ã¯æ¢ãŸãæäœã§ãã
ãšã©ãŒ3ã«çœ®ããã®ã¯ãåããã¹ /hello ã®äºéäœæãmotoã§ã¯201(æå)ãè¿ããŸããããå®éã®AWSã§ã¯åã芪ã«åãpathPartã¯äœãããConflictExceptionã§æ¢ãŸããŸãã
ãšã©ãŒ4ã«çœ®ããã®ã¯ãçµ±åã匵ã£ãŠããªãã¡ãœãããå«ããããã€ããã¡ããmotoã§ã¯éããŸããããå®éã®AWSã¯ãNo integration defined for methodãã§æ¢ããŠããŸãã
ãšã©ãŒ3ã§201ãè¿ã£ãŠããæç¹ã§ã¹ã¯ãªããã®ãã¹ãçããmotoã®ãœãŒã¹(apigateway/models.py ã® create_resource)ãéããŸããããã¹æååã®åœ¢åŒãã§ãã¯ã ãã§éè€ãã§ãã¯ã¯ç¡ãããã®ãŸãŸåãªãœãŒã¹ã远å ããŠããŸãããã¹ã¯ãªããã§ã¯ãªãmotoåŽã®ä»æ§ã§ãããã®2ã€ãå®AWSã§æ¢ãŸãæ¹ã¯ãããã¥ã¡ã³ããšéå»ã®ãšã©ãŒå ±åã§ç¢ºèªããã ãã§ãç§èªèº«ã¯ãŸã æ¬çªã§èžãã§ããŸãããèžãã ã远èšããŸãã
䌌ããµãŒãã¹ãšã®äœ¿ãåã
ãLambdaã«å ¬éURLãä»ãããã ããªããå®ã¯ä»ã«ãéããããŸãã
| æ¹æ³ | åããŠããå Žé¢ |
|---|---|
| API Gateway | ãã¹ãã¡ãœãããè€æ°ãããèªèšŒãæµéå¶éãããã |
| Lambda Function URL | 颿°1åã«URLã1æ¬ä»ããã ãã§ãã |
| ALB(ããŒããã©ã³ãµãŒ) | EC2ãã³ã³ãããšæ··ããŠæ¯ãåããã |
Lambda Function URLã¯2022幎ã«ç»å Žãã軜éãªéžæè¢ã§ã颿°ã®èšå®ç»é¢ãã1ã¯ãªãã¯ã§URLãåºãŸããã¡ãã¥ãŒã1åã§èªèšŒãèŠããªããªãããã§è¶³ããŸããåæ°ãå¢ããŠãGETã¯èŠãã ããPOSTã¯ç»é²ãDELETEã¯ç®¡çè ã ããã®ãããªéžå¥ãèŠã段éã«ãªã£ãããAPI Gatewayã«ä¹ãæãããã·ãªãŒãº20æ¬ç®ã§çµãäºå®ã®åçã¢ããªã¯ãã¹ãè€æ°ã«ãªãã®ã§ãç§ã¯API Gatewayã䜿ãã€ããã§ãã
æéã®èãæ¹
ãªã¯ãšã¹ãæ°ã®åŸé課éã§ããäœã£ãã ããªã0åãREST APIã¯100äžãªã¯ãšã¹ããããæ°ãã«å°(æ±äº¬ãªãŒãžã§ã³)ãHTTP APIãªããã®3åã®1çšåºŠã§ãç·Žç¿ã¢ããªãªãæã«æ°åãè¡ããŸããã
1ã€ã ããå ¬éURLã¯äžçäžããå©ããŸãã誰ãã«å€§éã«å©ãããããã®åã¯èª²éãããã®ã§ã䜿ãçµãã£ãAPIã¯æ¶ããŠãã ãããåé€ã®é çªã¯äžã§å®æž¬ããéãã§ãã
ããããæ³šæç¹
äžçªèžãŸããŠããã®ã¯ãèšå®ãå€ããã®ã«åæ ãããªããã§ãã
åå ã¯ãããã€ã®ããå¿ãã§ããAPI Gatewayã®èšå®å€æŽã¯ããªãœãŒã¹ãè¶³ããŠãã¡ãœãããå€ããŠããåãããã€ãããŸã§ã¹ããŒãžã«ã¯åæ ãããŸãããç·šéç»é¢ã§ã¯æ°ãããªã£ãŠããã®ã«URLãå©ããšå€ããŸãŸããšããç¶æ
ãèµ·ããŸãã察åŠã¯ãå€ããã create_deployment ããã1åãããã ãã
ãã1ã€ã¯ã404ãåºããšãã«URLã®ã¹ããŒãžåãçãããšã§ãã.../hello ãšæã£ãŠ404ã§ããæ£ãã㯠.../prod/hello ãããããŸãããURLã®åœ¢(ã¹ããŒãžåããã¹ã®å
é ã«å
¥ã)ãæãåºããŠãã ããã
ãŸãšã
ãThe REST API doesn't contain any methodsãã¯ãã¡ãœããã1ã€ãäœãããããã€ãããšãã®ãšã©ãŒã§ããããªãœãŒã¹ãšã¡ãœãããå ã«äœãã°éããŸãããå€ããã®ã«å€ããŸãŸãã¯åãããã€å¿ããAPI Gatewayã¯4éå±€ç®ã®ãããã€ããããŸã§ãäœãã©ãå€ããŠãäžã«åºãŸããã
æ¶ãé çªã¯ã¹ããŒãžâãããã€âæ¬äœãäœãé çªã®éã§ããmotoã§éã£ãæäœãæ¬çªã§ãéãä¿èšŒã¯ç¡ããåçŸæŒã2ã€(ãã¹ã®äºéäœæãšçµ±åãªããããã€)ããã®å®äŸã§ãã
次åã¯ECSã§ããLambda1åã§æããªãèŠæš¡ã®è©±ãããŸãã


