究竟哪条路径可以用于LocalStack API Gateway Lambda集成?

时间:2018-01-13 01:09:13

标签: aws-lambda aws-api-gateway atlassian-localstack

LocalStack很整洁,但很难找到它的文档。我无法访问连接到Lambda函数的API网关代理端点。

我能想到的唯一事情就是当我为网关进行put-integration时,我不知道如何处理凭证参数(假设这是100%本地...我没有真正的AWS账户'我正在使用)所以我现在留下它评论:

aws --endpoint-url=http://localhost:4567 apigateway \
    put-integration \
    --region us-west-2 \
    --rest-api-id 0091232159 \
    --resource-id 3732709762 \
    --http-method ANY \
    --type AWS_PROXY \
    --integration-http-method POST \
    --uri arn:aws:lambda:us-west-2:000000000000:function:PostProposal \
    #--credentials arn:aws:iam::123456789012:role/apigAwsProxyRole

我的同事发现了一个线程,听起来好像是LocalStack中的一个错误:

https://github.com/atlassian/localstack/issues/129

无论如何,这是我aws --endpoint-url=http://localhost:4567 apigateway get-resources --rest-api-id 0091232159时我的API的样子:

{
    "items": [
        {
            "id": "3312801A-ZA-Z6",
            "path": "/",
            "resourceMethods": {
                "GET": {}
            }
        },
        {
            "id": "3732709762",
            "parentId": "3312801A-ZA-Z6",
            "pathPart": "{proxy+}",
            "path": "/{proxy+}",
            "resourceMethods": {
                "GET": {},
                "ANY": {
                    "httpMethod": "ANY",
                    "authorizationType": "NONE",
                    "methodIntegration": {
                        "type": "AWS_PROXY",
                        "httpMethod": "ANY",
                        "uri": "arn:aws:lambda:us-west-2:000000000000:function:PostProposal",
                        "integrationResponses": {
                            "200": {
                                "statusCode": 200,
                                "responseTemplates": {
                                    "application/json": null
                                }
                            }
                        }
                    }
                }
            }
        }
    ]
}

我的Lambda功能全部设置完毕,当我这样做时会响应200:

aws --endpoint-url=http://localhost:4574 lambda invoke --function-name PostProposal outfile.json

现在我只想要一个将触发Lambda的端点。

我找到了这个帖子:https://github.com/localstack/localstack/issues/229,其中有一个cURL示例:

curl http://localhost:4567/restapis/35937034A-Z3/test/_user_request_/u-1234

还有一个:https://bitbucket.org/atlassian/localstack/issues/4/how-to-create-api-gateway-deployments有:

curl http://localhost:4567/restapis/$api_id/v1/_user_request_/mypath

我知道我的API ID,'v1'与我的'test'阶段名称相关。我的终点位于根,所以我认为我不需要他的路径。

所以我尝试使用GET和POST尝试所有不同类型的路径:

curl http://localhost:4567/restapis/0091232159/test/_user_request_/

我收到了404,500和{"message": "Unable to find integration for path ...的各种回复。

我至少要点击API Gateway模拟服务器;当我卷曲-vv时,我看到:

* Connected to localhost (127.0.0.1) port 4567 (#0)
> GET /restapis/0091232159/test/_user_request_/ HTTP/1.1
> Host: localhost:4567
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 404 Not Found

有什么想法吗?我只需要神奇的道路!

1 个答案:

答案 0 :(得分:1)

您是否部署了API?我没有看到上面的命令。如果是,如果您在浏览器中打开http://localhost:4567/restapis,则应该是可见的。

可以肯定的是,这是在Localstack中使用API​​网关设置lambda的完整演练:

首先我们创建一个简单的NodeJS Lambda:

const apiTestHandler = (payload, context, callback) => {
console.log(`Function apiTestHandler called with payload ${JSON.stringify(payload)}`);
callback(null, {
    statusCode: 201,
    body: JSON.stringify({
        somethingId: payload.pathParameters.somethingId
    }),
    headers: {
        "X-Click-Header": "abc"
    }
}); 
}
module.exports = {
    apiTestHandler,
}

将其放入名为apiTestHandler.zip的zip文件中并将其上传到localstack:

aws lambda create-function \
--region us-east-1 \
--function-name api-test-handler \
--runtime nodejs6.10 \
--handler index.apiTestHandler \
--memory-size 128 \
--zip-file fileb://apiTestHandler.zip \
--role arn:aws:iam::123456:role/role-name --endpoint-url=http://localhost:4574

现在我们可以创建我们的Rest-Api:

aws apigateway create-rest-api --region us-east-1 --name 'API Test' --endpoint-url=http://localhost:4567

这给出了以下回应:

{
"name": "API Test",
"id": "487109A-Z548",
"createdDate": 1518081479
}

根据我们在这里获得的ID,我们可以询问其父ID:

aws apigateway get-resources --region us-east-1 --rest-api-id 487109A-Z548 --endpoint-url=http://localhost:4567

响应:

{
"items": [
    {
        "path": "/",
        "id": "0270A-Z23550",
        "resourceMethods": {
            "GET": {}
        }
    }
]
}

现在我们拥有了创建资源及其路径的所有内容:

aws apigateway create-resource \
--region us-east-1 \
--rest-api-id 487109A-Z548 \
--parent-id 0270A-Z23550 \
--path-part "{somethingId}" --endpoint-url=http://localhost:4567

响应:

{
"resourceMethods": {
    "GET": {}
},
"pathPart": "{somethingId}",
"parentId": "0270A-Z23550",
"path": "/{somethingId}",
"id": "0662807180"
}

创建链接的GET方法需要我们在这里获得的ID:

aws apigateway put-method \
 --region us-east-1 \
 --rest-api-id 487109A-Z548 \
 --resource-id 0662807180 \
 --http-method GET \
 --request-parameters "method.request.path.somethingId=true" \
 --authorization-type "NONE" \
--endpoint-url=http://localhost:4567

我们几乎就在那里 - 最后要做的事情之一是创建与已上传的lambda的集成:

aws apigateway put-integration \
 --region us-east-1 \
 --rest-api-id 487109A-Z548 \
 --resource-id 0662807180 \
 --http-method GET \
 --type AWS_PROXY \
 --integration-http-method POST \
 --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:api-test-handler/invocations \
 --passthrough-behavior WHEN_NO_MATCH \
 --endpoint-url=http://localhost:4567

最后但并非最不重要:将我们的API部署到我们期望的阶段:

aws apigateway create-deployment \
 --region us-east-1 \
 --rest-api-id 487109A-Z548 \
 --stage-name test \
 --endpoint-url=http://localhost:4567

现在我们可以测试一下:

curl http://localhost:4567/restapis/487109A-Z548/test/_user_request_/HowMuchIsTheFish

响应:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                             Dload  Upload   Total   Spent    Left  Speed
100    34  100    34    0     0      9      0  0:00:03  0:00:03 --:--:--     9
{"somethingId":"HowMuchIsTheFish"}

我希望这会有所帮助。

提示1 :为了便于使用,我建议安装AWSCLI Local(https://github.com/localstack/awscli-local) - 使用此工具,您可以使用命令“awslocal”,而不必输入“ - -endpoint-url = ...“对于每个命令

提示2 :如果您不希望每次都手动定义上述步骤,我建议您使用无服务器框架(https://serverless.com/)和localstack插件(https://github.com/temyers/serverless-localstack)。如果您需要帮助,我也可以为您提供简短指南。