20

I am using API Gateway in Amazon as a simple proxy to a backend api. The main reasons for using it are: a simple way to get API keys and authentication, tracking, and handling "environments".

My problem is that, we just want to pass through all query parameters, headers, etc. to our backend and let it handle it. Then on the way back, we'd like to pass back to the client the appropriate response code from our service; not have to explicitly map them. As I understand it, you pretty much have to specify every query parameter, and if the parameters change or you add more, you need to update your api. This is sort of tedious for us during dev/test.

Is there a way to tell Gateway to just accept and pass through any query parameters, headers, etc. so that you dont have to specify them explicitly? Same question for response Status codes?

alph486
  • 1,209
  • 2
  • 13
  • 26

3 Answers3

14

Unfortunately no there is no way to do a passthrough of all parameters, you have to state each one in the method request. Same answer for status codes.

We've since launched the 'proxy' integration for HTTP endpoints and Lambda functions that will act as a proxy for the request input and send all parameters plus the payload to the integration. For Lambda functions, there is a prebuilt JSON structure that contains all parameters and the payload, as well as request context and stage variables.

See this doc: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-proxy-resource

This is a feature request we've had in the past and it's on our backlog, but no ETA at this time. I'll take this as another +1 for both passthrough features.

jackko
  • 6,998
  • 26
  • 38
  • @jack-kohn-aws I need to pass through a filter query param. e.g. https://api.xxx/pets?filters[search]=cute How would I achieve this? – rabishah Apr 11 '16 at 10:18
  • +1. This would be a great help to folks trying to migrate legacy APIs full of ad-hoc endpoints with little documentation of query parameters. – Eric Jul 06 '16 at 20:40
  • I think this is already possible :-) https://aws.amazon.com/about-aws/whats-new/2016/09/amazon-api-gateway-introduces-3-new-features-to-simplify-api-configuration/ – plewandowski Aug 16 '17 at 11:04
  • It says there you can capture all path parameters using a greedy path variable like `{proxy+}`. Is it also possible to specify e.g. `{proxy*}` to allow the `pathParameters` to be empty? – Vincent Sep 06 '17 at 07:19
11

For the request, there are mappings to easily pass through everything, this is one I've used recently:

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "queryParams": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "pathParams": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "stage-variables" : {
    #foreach($key in $stageVariables.keySet())
      "$key" : "$util.escapeJavaScript($stageVariables.get($key))"
      #if($foreach.hasNext),#end
    #end
  },
  "context" : {
    "account-id" : "$context.identity.accountId",
    "api-id" : "$context.apiId",
    "api-key" : "$context.identity.apiKey",
    "authorizer-principal-id" : "$context.authorizer.principalId",
    "caller" : "$context.identity.caller",
    "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
    "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
    "cognito-identity-id" : "$context.identity.cognitoIdentityId",
    "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
    "http-method" : "$context.httpMethod",
    "stage" : "$context.stage",
    "source-ip" : "$context.identity.sourceIp",
    "user" : "$context.identity.user",
    "user-agent" : "$context.identity.userAgent",
    "user-arn" : "$context.identity.userArn",
    "request-id" : "$context.requestId",
    "resource-id" : "$context.resourceId",
    "resource-path" : "$context.resourcePath"
  }
}

It loops through all the headers and parameters to map everything. There is also a new feature that was announced yesterday which allows you to pass the raw request body.

I think you could take a similar approach to creating a universal response mapping. You might want to look at the parseJson() mapping function which was also announced yesterday. I believe the new parseJson() function would allow you to return a string containing JSON data from your backend, and have that easily mapped to a JSON response in API gateway.

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • Where does this go? Is this something in a lambda or somewhere else? It's not swagger from the looks of it. Can you add some more context to your answer? – EdgeCaseBerg Sep 27 '17 at 17:55
  • 1
    @EdgeCaseBerg It is an AWS API Gateway request mapping template. Documented here: http://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html – Mark B Sep 27 '17 at 18:33
2

I believe you can use http-proxy feature of API Gateway - which will take all the parameters the way you send to it - to your mentioned EC2 URL or any other URL

Abdeali Chandanwala
  • 8,449
  • 6
  • 31
  • 45