1

I have an AWS lambda function (nodejs) that will return a pdf with Content-Type: "application/pdf".

I learned how to prepare it for deployment in a container image, and the documentation says i can invoke it locally with curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}',
where the -XPOST seems unnecessary as the function will just read the request body provided by --data/-d even if it's from the default -XGET.

Either way, at this point i'm not processing any request body yet, and i could as well not even intend to, but if i omit the request body (or provide an invalid json like -d "abc"), the Runtime Interface Client fails before even invoking my function with this error:

 {"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)"
]}

(or Unexpected token a in JSON at position 0, for the -d "abc")

If i could access the local function url from browser, i could immediately see the returned pdf result, but there's no way to provide a dummy request body there. How do I allow the lambda interface to accept simple get requests without a body?

bpstrngr
  • 339
  • 3
  • 13
  • 1
    That's a classic JSON.parse exception in your code, can you share your lambda function code? – Himanshu Pant Oct 13 '22 at 17:53
  • @HimanshuPant my lambda function doesn't parse any JSON, this is returned by the aws-lambda-ric before entering my function. Mind the "file:///var/runtime/index.mjs:1089:42" in the stack trace. When I invoke my function directly with nodejs (eg. node -e 'import("lambda.js").then(({handler})=>handler())' ), or provide the -d "{}" body it demands, the response pdf is returned without error. – bpstrngr Oct 13 '22 at 17:56
  • Might be worth checking out the index.mjs file and walking through the stack trace. – Himanshu Pant Oct 13 '22 at 18:15
  • @HimanshuPant do you mean I should edit aws-lambda-ric's source code and specify a new ENTRYPOINT in my container calling a `node ./hacked-aws-lambda-ric/bin/index.js $@` script? I did find the place where it parses the JSON in the package, but this doesn't sound very recommendable. – bpstrngr Oct 13 '22 at 18:31

1 Answers1

1
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

A POST request here doesn't mean your Lambda is required to process a POST request. Because here you're invoking the aws-lambda-ric, not the Lambda itself. The runtime interface client is designed in a way to accept a POST request, and then, it invokes your local Lambda.

Inside -d '{}' you then provide the exact payload your Lambda is expected to receive as the event argument.

If your Lambda designed to work with API GW trigger, and accept only GET requests, then it will look smth like:

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}'

Sample GET request payload for the event argument is taken from documentation.

So you mock a GET request by modifying what you pass inside -d '{}' (see where the example command has {"resource":"/","path":"/","httpMethod":"GET").

Not by changing the HTTP method of aws-lambda-ric.

Vlad Holubiev
  • 4,876
  • 7
  • 44
  • 59
  • amazing heureka response, thanks! – bpstrngr Oct 13 '22 at 19:41
  • I've marked it as accepted, btw this probably implies that there's simply no way to "visit" the aws-lambda-ric from a common browser. unless this is intentional, it seems like pointless a limitation. – bpstrngr Oct 13 '22 at 19:48
  • @bpstrngr yes, this is intentional, and there is no way to "visit" it from browser. If you absolutely need this, you can write a small http server as a "wrapper" that will proxy a GET request from your browser to a POST request from aws-lambda-ric – Vlad Holubiev Oct 13 '22 at 19:53