2

I'm replacing the AWS API Gateway in front of my Lambda by calling it directly from the AWS Java SDK using Invoke

InvokeRequest request = new InvokeRequest();
try {
    request.putCustomQueryParameter("city", "Seattle");
    request.withFunctionName(functionName).withPayload(ByteBuffer.wrap(IOUtils.toByteArray(content)));
} catch (IOException e1) {
    e1.printStackTrace();
}

Is there a way to pass in headers or query parameters along with the request? I tried the code above but all I'm able to send is the payload.

djuang1
  • 23
  • 3
  • Have you tried [putCustomRequestHeader](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/AmazonWebServiceRequest.html#putCustomRequestHeader-java.lang.String-java.lang.String-) on invoke request? – markw Sep 08 '20 at 23:42
  • Yeah, I tried both but neither work. The payload is the only thing that is getting passed in the request. – djuang1 Sep 09 '20 at 14:54
  • A query parameter implies HTTP with a URL parameter. Where do you expect the query parameters to show up in the target Lambda? – stdunbar Sep 10 '20 at 01:10
  • See the function code in this [example](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html). My Lambda also pulls the _queryStringParameters_ in the code but it seems that the AWS Java SDK doesn't allow you to pass the query parameters or headers in to the request. – djuang1 Sep 10 '20 at 16:11

1 Answers1

1

Quick answer: the putCustomRequestHeader can only be used to add request headers to the HTTP request which is send to the AWS Lambda Service. They'll not be forwarded to the AWS Lambda Function.

Long answer: I believe you are mixing up two different things here and there's a misunderstanding of the terminology. If you invoke an AWS Lambda Function, you'll send an HTTP request to the AWS Lambda Service which will then perform the actual invocation of a Lambda function (and it forwards your payload data to the function). For example, the AWS Lambda Service looks if there is an idle function and uses it, otherwise it starts a new instance of your function and uses that.

a) Directly Invoke AWS Lambda

If you want to invoke an AWS Lambda Function using the AWS SDK, you do this from within your code, e.g. a Java program:

Java Program --> Invoke AWS Lambda Function

This means, your code is directly invoking a Lambda function. In such a case, you can only provide a payload to the function. If you want to add any "additional" data, you can only extend the payload data.

b) Indirectly Invoke AWS Lambda

Then there is a way to "indirectly" invoke a Lambda function, e.g. a function that sits behind an API Gateway. Such a Lambda function can receive HTTP headers and query parameters because the API Gateway is receiving an HTTP request and forwarding an HTTP event to the AWS Lambda function:

Java Program --> Send HTTP request --> API Gateway receives HTTP --> API Gateway invokes AWS Lambda Function with HTTP event data

In the last step where the API Gateway invokes the AWS Lambda Function, the API Gateway will also "just" invoke the Lambda function. But it provides all the HTTP data (that it received before) as the payload data for the Lambda function. That's why you have access to HTTP headers and query parameters in this scenario.

Solution to your question

If you really need to provide HTTP headers or query parameters, then put an API Gateway in front of your function. However, if you just want to invoke your function from within your code, then simply extend the payload data that you're sending and add the data you'd like to provide.

s.hesse
  • 1,900
  • 10
  • 13
  • Thanks for the detailed answer. That's the conclusion that I've come to as well. I'm trying to make the transition easier as I migrate my Lambda functions away from AWS API Gateway. Some of my APIs are using _Lambda proxy integration_ which is the reason for my question. – djuang1 Sep 11 '20 at 16:03