1

I am using AWS API Gateway and I want to set my Integration type to http. I have the integrated url as https:// xxxxxx.com which takes a header "apikey". I am not expecting the end user to pass the header rather I want to set the apikey to some constant value.

I see that there is a way to force the user to make him pass the header(by making header required under the Method Request section. However, I want to set it to default.

For example in all the requests which are internally calling the URL inside the API gateway should pass the header value as "12345".

Dhana
  • 505
  • 1
  • 8
  • 27
  • I'm trying to make sense of your question. Are you saying that the endpoint behind the api gateway requires an api key which you wish to hide from the people calling the API Gateway? – K Mo Nov 16 '19 at 09:47
  • KMo Yes. The API GAteway calls a http. That http requires an apikey. – Dhana Nov 18 '19 at 06:26

2 Answers2

3

You can add/remove/override headers with an Integration Request Mapping Template.

In the API Gateway console, chose the relevant api/resourece/method. Go to Integration Request > Mapping Templates and chose your Content-Type (if requests are going to be received without a Content-Type header, set the Content-Type for the mapping template to application/json, which is the default behaviour).

Then in the actual mapping template add the following:

{
    #set($context.requestOverride.header.apikey= "testMe")
}

This will add (or overwrite if it already exists) a header called apikey with the value "testMe" to all http requests downstream.

If you take this route, then you will need to also map over any other headers, path parameters, query parameters or body that you wish to pass through.

You could loop through the headers and query parameters like this.

## First set the header you are adding
#set($context.requestOverride.header.apikey= "testMe")

## Loop through all incoming headers and set them for downstream request
#foreach($param in $input.params().header.keySet())
    #set($context.requestOverride.header[$param]= $input.params().header.get($param))
    #if($foreach.hasNext) #end

    #end 

## Loop through all incoming query parameters and set them for downstream request
#foreach($param in $input.params().querystring.keySet())
    #set($context.requestOverride.querystring[$param]= $input.params().querystring.get($param))
    #if($foreach.hasNext) #end

    #end   

As you need to ensure that the header apikey is set to a default value, you should set the override for apikey before looping through the rest of the headers as only the first override will take effect.

The relevant AWS documentation can be found here.

The other alternative would be to point your API Gateway at a Lambda and make the call from the Lambda instead.

K Mo
  • 2,125
  • 8
  • 16
  • Seems like it worked but I am getting the answer in Unicode format. One which is not human readable. getting a 200 response. Am I doing something wrong? Also I am passing a Query parameter to the URL. Will it get passed to the downstream http? – Dhana Nov 18 '19 at 15:16
  • 1
    In regards to the response, it is hard to say without knowing what you are calling, but you may need to set an accept header in the same way you set the apikey header. In regards to query params, you'll need to set these too. Information on how to do that is in the linked doc. If your querying different things in each request, you'll need to loop through what has been sent or add a bunch of if statements. The mapping uses Velocity Template Language, plenty of info on Google. – K Mo Nov 18 '19 at 15:31
  • @K Mo, sorry to bother you, but can you tell me how to get the value of Query string from upstream to downstream. I tried this but it is hardcoded. I need the value from upstream:- #set($context.requestOverride.querystring.country="IND") I may need what is passed in the actual URL. Thanks in anticipation. – Dhana Nov 18 '19 at 15:43
  • if you ever are only going to need a query param for country, you can just add `#set($context.requestOverride.querystring.country= $input.params(country))` otherwise you'll have to loop through all of the params and set them individually. – K Mo Nov 18 '19 at 19:53
  • @Dhana I've added a second mapping example that brings over all headers and query parameters while ensuring that the header 'apikey' is set to a default value. – K Mo Nov 18 '19 at 21:10
  • I appreciate your patience. Please see my answer. Thanks a ton. – Dhana Nov 19 '19 at 07:06
1

Firstly thanks to @KMO for his help. The following is the solution:-

  1. Enable Http Proxy Integration.
  2. Add the headers apikey=xxxx and Accept-Encoding=identity under the same Integration Request -> Http Headers.
  3. Under Settings -> Binary Media Types set the following as separate Binary Media Types '*', */*. I mean as two different lines.This step is needed to resolve the Gzip action while returning the response.
  4. Add the Query parameter country in the URL Query String Parameters section.
  5. In the Integration Request map the country parameter to ctry by adding the value under mapped from as method.request.querystring.country. This will ensure that the query parameter country you passed in the main URL will be fed to the downstream url as parameter ctry.

The advantage of this apporoach is that, even if you override the header apikey, the one set under the Http Headers will take the precedence.

Dhana
  • 505
  • 1
  • 8
  • 27
  • Refer to the link:-https://stackoverflow.com/questions/39453097/how-to-return-gzipped-content-with-aws-api-gateway – Dhana Nov 19 '19 at 10:21
  • i dont see this option for proxy integration ? how can I set default API key to my underlying HTTP from gateway. if I see my API key under headers, it doesn't allow me to save causing "INvalid Mapping Expression" – virendrao Jan 18 '22 at 08:47