Parameters mapping from method.paths to integration.headers

We are using serverless to deploy an api-gateway to act as a single point of entry to other api endpoints. The serverless project does not have any lambda logic and the functions is just a dummy handler with an http event that proxy the request to the final endpoint.

For example in the function definition works perfectly:

functions:

  hello:
    handler: handler.endpoint
    events:
      - http:
          method: ANY
          path: /{versionId}/hello/{proxy+}
          integration: http-proxy
          request:
            uri: https://example.com/hello
            parameters:
              paths:
                 versionId: true

what we would like to do is to map the ‘versionId’ parameter from the method.path, to the headers like so:

   method: ANY
      request:
         uri: https://example.com/hello
         parameters:
            paths:
               versionId: true
    integration: http-proxy
        request:
           parameters:
              headers: 
                 x-custom-version: method.request.path.versionId

it looks like serverless only support like to like mapping (header to header) but not cross mapping (path to header).

One way I could solve this is to use cloudformation in the resource section, and obviously, that is not as readable and maintainable compared to defining those endpoints using yml under the function section in serverless.yml.

Before I make a feature request in github, I want to raise it here first to see what are the thoughts from the community about allowing developers to define how they want to map the parameters from method to integration for http-proxy endpoints.

2 Likes

What does the expected resultant CF would look like?

if we going to use cloudformation, it will look something like

resources:
  Resources:
    ApiGatewayRestApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: ${self:service}
        Description: 'The main entry point of test APIs'
            
    VersionBasePath:
      Type: AWS::ApiGateway::Resource
      Properties:
        ParentId:
          Fn::GetAtt:
            - ApiGatewayRestApi
            - RootResourceId
        PathPart: '{versionId}'
        RestApiId:
          Ref: ApiGatewayRestApi    
    MainApiBasePath:
      Type: AWS::ApiGateway::Resource
      Properties:
        ParentId:
          Ref: VersionBasePath
        PathPart: 'main-api'
        RestApiId:
          Ref: ApiGatewayRestApi
    MainApiProxyPath:
      Type: AWS::ApiGateway::Resource 
      Properties:
        ParentId:
          Ref: MainApiBasePath
        PathPart: '{proxy+}'
        RestApiId:
          Ref: ApiGatewayRestApi
    MainApiProxyAnyMethod:
      Type: AWS::ApiGateway::Method 
      Properties:
        AuthorizationType: NONE
        HttpMethod: ANY
        Integration: 
          IntegrationHttpMethod: ANY
          Type: HTTP_PROXY
          Uri: https://example.com/hello/{proxy}
          PassthroughBehavior: WHEN_NO_MATCH
          RequestParameters: 
            'integration.request.header.x-custom-versionId': 'method.request.path.versionId'
        MethodResponses:
          - StatusCode: 200
        RequestParameters: 
          'method.request.path.versionId': true
        ResourceId:
          Ref: MainApiProxyPath
        RestApiId:
          Ref: ApiGatewayRestApi