从容器调用 AWS lambda 函数,无需请求正文

问题描述 投票:0回答:2

我有一个 AWS lambda 函数(nodejs),它将返回内容类型为“application/pdf”的 pdf。

我学习了如何准备在容器映像中部署它, 文档说我可以在本地调用它

curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
,
其中 -XPOST 似乎没有必要,因为该函数只会读取 --data/-d 提供的请求正文,即使它来自默认的 -XGET。

无论哪种方式,此时我还没有处理任何请求主体,我什至也可能不打算处理,但如果我省略请求主体(或提供像

-d "abc"
这样的无效json),运行时接口客户端在调用我的函数并出现此错误之前就失败了:

 {"errorType":"SyntaxError"
 ,"errorMessage":"Unexpected end of JSON input"
 ,"trace":
["SyntaxError: Unexpected end of JSON input"
,"    at JSON.parse (<anonymous>)"
,"    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1089:42)"
]}

(或

Unexpected token a in JSON at position 0
,对于
-d "abc"

如果我可以从浏览器访问本地函数 url,我可以立即看到返回的 pdf 结果,但无法在那里提供虚拟请求正文。 如何允许 lambda 接口接受没有正文的简单 get 请求?

node.js amazon-web-services aws-lambda container-runtime-interface
2个回答
4
投票
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

此处的 POST 请求并不意味着您的 Lambda 需要处理 POST 请求。因为在这里您调用的是

aws-lambda-ric
,而不是 Lambda 本身。运行时接口客户端的设计方式是接受 POST 请求,然后调用您的本地 Lambda。

-d '{}'
内部,您可以提供 Lambda 预期接收的确切负载作为
event
参数。

如果您的 Lambda 设计为与 API GW 触发器配合使用,并且仅接受 GET 请求,那么它将看起来像:

curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"resource":"/","path":"/","httpMethod":"GET","requestContext":{"resourcePath":"/","httpMethod":"GET","path":"/Prod/"},"headers":{"accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9","accept-encoding":"gzip, deflate, br","Host":"70ixmpl4fl.execute-api.us-east-2.amazonaws.com","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36","X-Amzn-Trace-Id":"Root=1-5e66d96f-7491f09xmpl79d18acf3d050"},"multiValueHeaders":{"accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"accept-encoding":["gzip, deflate, br"]},"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":null,"stageVariables":null,"body":null,"isBase64Encoded":false}'

event
参数的示例 GET 请求负载取自文档

因此,您可以通过修改在内部传递的内容来模拟 GET 请求

-d '{}'
(请参阅示例命令的位置
{"resource":"/","path":"/","httpMethod":"GET"
)。

不是通过更改

aws-lambda-ric
的 HTTP 方法。


0
投票

如果你正在尝试做这样的事情

const invokeLambdaLocally = async () => {
  const url = "http://localhost:9000/2015-03-31/functions/function/invocations";
  const headers = {
    'Content-Type': 'application/json'
  };
  const body = JSON.stringify({
    // Your Lambda function's expected event object structure
  });

  try {
    const response = await fetch(url, {
      method: 'POST', // Must be POST for aws-lambda-ric
      headers: headers,
      body: body
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return data;
  } catch (error) {
    console.error("Error invoking Lambda locally:", error);
  }
};
invokeLambdaLocally();

您可能需要包含如下所示的请求正文

{
  "body": "{\"message\": \"hello world\"}",
  "resource": "/{proxy+}",
  "path": "/path/to/resource",
  "httpMethod": "POST",
  "isBase64Encoded": false,
  "queryStringParameters": {
    "foo": "bar"
  },
  "pathParameters": {
    "proxy": "/path/to/resource"
  },
  "stageVariables": {
    "baz": "qux"
  },
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate, sdch",
    "Accept-Language": "en-US,en;q=0.8",
    "Cache-Control": "max-age=0",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-Country": "US",
    "Host": "1234567890.execute-api.us-east-1.amazonaws.com",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Custom User Agent String",
    "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)",
    "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==",
    "X-Forwarded-For": "127.0.0.1, 127.0.0.2",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
  },
  "requestContext": {
    "accountId": "123456789012",
    "resourceId": "123456",
    "stage": "prod",
    "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
    "requestTime": "09/Apr/2015:12:34:56 +0000",
    "requestTimeEpoch": 1428582896000,
    "identity": {
      "cognitoIdentityPoolId": null,
      "accountId": null,
      "cognitoIdentityId": null,
      "caller": null,
      "accessKey": null,
      "sourceIp": "127.0.0.1",
      "cognitoAuthenticationType": null,
      "cognitoAuthenticationProvider": null,
      "userArn": null,
      "userAgent": "Custom User Agent String",
      "user": null
    },
    "path": "/prod/path/to/resource",
    "resourcePath": "/{proxy+}",
    "httpMethod": "POST",
    "apiId": "1234567890",
    "protocol": "HTTP/1.1"
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.