Search code examples
amazon-web-servicescorsaws-api-gatewayaws-appsync

How can I add CORS on apigateway http_proxy without setting a lambda?


I have a API gateway and there are a few paths defined in the gateway. I'd like to enable CORS to one of the path which works as http_proxy pointing to an appsync in the backend. The appsync resolvers point to a dynamodb table. so frontend calls API gateway who pass the requests to appsync and the request is resolved by dynamodb.

My problem is to enable CORS on that particular path. But based on this doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html it says I have to response the CORS header in backend which is a lambda. But I don't have a lambda in the backend. All the backends are just appsync + some resolvers (e.g. Dynamodb). How can I make it support CORS?

When I call appsync endpoint directly, it response access-control-allow-origin: * and it works fine for frontend (a web site). However, if the frontend calls API gateway domain, it will get rejected because of cors. I believe apigateway doesn't allow CORS so how can I enable cors in http_proxy integration without a backend lambda?


Solution

  • Let's say you have the following CloudFormation declaration for your GraphQL based HTTP_PROXY integration for POST method

    GraphQLPostMethod:
        Type: AWS::ApiGateway::Method
        Properties:
          HttpMethod: POST
          Rest of the properties for HTTP_PROXY integration
    

    Define one more method for OPTIONS request. If the source i.e. AppSync responds to Options request with appropriate headers, you should be fine with a HTTP_PROXY integration. If it doesn't or you don't want to send the Options request to AppSync, in that case you can use the MOCK integration for the Options method.

    GraphQLOptionsMethod:
        Type: AWS::ApiGateway::Method
        Properties:
          AuthorizationType: NONE
          HttpMethod: OPTIONS
          ResourceId: !Ref <ReplaceWithYourResrouce>
          RestApiId: !Ref <ReplaceWithYourAPI>
          MethodResponses:
            - ResponseModels:
                application/json: Empty
              ResponseParameters:
                method.response.header.Access-Control-Allow-Headers: true
                method.response.header.Access-Control-Allow-Methods: true
                method.response.header.Access-Control-Allow-Origin: true
              StatusCode: '200'
          Integration:
            Type: MOCK
            IntegrationResponses:
              - ResponseTemplates:
                  application/json: ''
                StatusCode: '200'
                ResponseParameters:
                  method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
                  method.response.header.Access-Control-Allow-Methods: "'POST'"
                  method.response.header.Access-Control-Allow-Origin: !Sub "'${ReplaceWithYourCORSAllowedOrigin}' or hardcode to *"
            PassthroughBehavior: NEVER
            RequestTemplates:
              application/json: '{"statusCode": 200}'