Hamed Minaee
Hamed Minaee

Reputation: 2560

cloudformation does not attach the requested path param in api gateway

I am trying to create api gateway in cloudformation. everything is good except when I specify path param url I can see it in the api gateway created. Here is my cfn code:

GetMethod:
Type: AWS::ApiGateway::Method
Properties:
  AuthorizationType: NONE
  HttpMethod: GET
  Integration:
    Type: HTTP
    IntegrationHttpMethod: GET
    Uri:
      Fn::Join:
      - ''
      - - "http://"
        - Fn::ImportValue: !Sub ${project}-${EnvironmentApp}-bn-user-endpoint-url
        - "/users"
        - "/{users}"
    IntegrationResponses:
    - StatusCode: 200
      ResponseParameters:
        method.response.header.Access-Control-Allow-Origin: "'*'"
      ResponseTemplates:
        application/json: ''
    RequestTemplates:
      application/json: ''
  RequestParameters:
    method.request.path.users: true
  ResourceId: !Ref UsersPathParam
  RestApiId:
    Ref: RestApi
  MethodResponses:
  - StatusCode: 200
    ResponseParameters:
        method.response.header.Access-Control-Allow-Origin: true

If you noticed in the code above I specifically ask for path param called users:

RequestParameters:
    method.request.path.users: true

Also, you can see the created API gateway that has no path param set in the attached image. Any ideas?

supporting image[1]

Upvotes: 3

Views: 6819

Answers (2)

Andrew
Andrew

Reputation: 1650

There are two RequestParameters properties: one belongs to the method and one belongs to the integration. Both the key and value serve slightly different purposes, which can understandably create confusion.

AWS documentation for the method property (emphasis added):

The request parameters that API Gateway accepts. Specify request parameters as key-value pairs (string-to-Boolean mapping), with a source as the key and a Boolean as the value. The Boolean specifies whether a parameter is required. A source must match the format method.request.location.name, where the location is querystring, path, or header, and name is a valid, unique parameter name.

AWS documentation for the integration property (emphasis added):

The request parameters that API Gateway sends with the backend request. Specify request parameters as key-value pairs (string-to-string mappings), with a destination as the key and a source as the value.

Specify the destination by using the following pattern integration.request.location.name, where location is querystring, path, or header, and name is a valid, unique parameter name.

The source must be an existing method request parameter or a static value. You must enclose static values in single quotation marks and pre-encode these values based on their destination in the request.

So the currently accepted answer is technically valid, but would likely result in the static value true being sent to the integration parameter instead of the method parameter value being passed to the integration. It is more likely that you want to provide a reference to the method parameter.

So, to explain the keys, the method RequestParameter key defines where to find the value in the method request and the integration RequestParameter key defines where to place the value in the integration request. This allows you to map the request parameters to completely different integration parameters if you'd like (e.g. placing a request path parameter into the integration querystring, changing the request parameter named foo to the integration parameter named bar, etc.)

You also may or may not require the method parameter to exist, so set the method parameter boolean value to true or false depending on whether you want to enforce that value must be included with the method request:

GetMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    RestApiId: !Ref RestApi
    ResourceId: !Ref Resource
    AuthorizationType: NONE
    HttpMethod: GET
    RequestParameters:
      - method.request.path.foo: true|false
    Integration:
      Type: HTTP
      IntegrationHttpMethod: GET
      Uri: https://example.com
      RequestParameters:
        - integration.request.path.foo: method.request.path.foo

Upvotes: 13

Laurent Jalbert Simard
Laurent Jalbert Simard

Reputation: 6329

Since it needs to be applied in the "integration request" part of the API, you must prefix the parameter with integration. Like so:

RequestParameters:
  integration.method.request.path.users: "'true'"

Also, notice the single quotes, I had to add those to add string literals there but YMMV.

EDIT: It looks like your RequestParameters is not indented at the right place. It should be under Integration: since it's something you want to add at that level.

EDIT 2: I've tested using this method and it worked flawlessly:

ProxyMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    ResourceId: !Ref ProxyResource
    RestApiId: !Ref RestApi
    AuthorizationType: AWS_IAM
    HttpMethod: ANY
    RequestParameters:
      method.request.path.proxy: true
    Integration:
      IntegrationHttpMethod: ANY
      Type: HTTP_PROXY
      Uri: !Sub ${BaseUrl}/{proxy}
      RequestParameters:
        integration.request.path.user: "'true'"

Upvotes: 1

Related Questions