aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.4k stars 2.12k forks source link

Decoupling host from destination URL when running AppSync behind a reverse proxy #13370

Open benvandenberg opened 2 months ago

benvandenberg commented 2 months ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

GraphQL API

Amplify Version

v6

Amplify Categories

api

Backend

CDK

Environment information

``` System: OS: Linux 5.15 Ubuntu 20.04.6 LTS (Focal Fossa) CPU: (12) x64 Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz Memory: 9.86 GB / 15.38 GB Container: Yes Shell: 5.0.17 - /bin/bash Binaries: Node: 20.12.1 - ~/git/ui/front-end/.venv/bin/node Yarn: 3.2.3 - ~/git/ui/front-end/node_modules/.bin/yarn npm: 10.5.0 - ~/git/ui/front-end/.venv/bin/npm Browsers: Chrome: 124.0.6367.155 npmGlobalPackages: corepack: 0.25.2 npm: 10.5.0 ```

Describe the bug

I am a platform developer, and working with a front end application that uses the amplify-js library to create subscriptions to AppSync.

We are running AppSync behind a reverse proxy: client -> ALB -> EC2 (NGINX) -> AppSync

The reverse proxy allows us to route requests through a single endpoint, which is important to our customers given their strict firewall rules.

I am able to write native code that let's a client create subscriptions to AppSync through the reverse proxy. However, our front end team uses the amplify-js library. I am unable to see a way to decouple the "host" from the request URL. When configuring the client, the "aws_appsync_graphqlEndpoint" value is used for both the host (the AppSync domain, used when setting up the websocket) and the destination of the request. In our case, we want the request to go to the URL assigned to the reverse proxy, but have the host value, used when setting up the websocket, be the AppSync domain.

Support for proxies was implemented as part of https://github.com/aws-amplify/amplify-js/commit/6d5afce390687e925438d6d208a18c84e61399a9, but does not work for subscriptions.

Expected behavior

The GraphQL API allows the customEndpoint to be set for subscriptions. The "host" should be the AppSync URL, while the requests should be sent to the custom endpoint.

Reproduction steps

Setup a reverse proxy using NGINX, and assign a URL to a Load Balancer.

Code Snippet

The location block of NGINX can be setup like this:

       location /graphql/realtime {
            proxy_pass https://some-aws-defined-value.appsync-realtime-api.us-east-1.amazonaws.com/graphql;
            proxy_redirect default;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection upgrade;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Authorization $http_authorization;

            # Connection establishment timeout
            proxy_connect_timeout 10s;

            # Read timeout. This value will close a websocket waiting on a subscription.
            # AppSync has a 30s limit for HTTP requests, and a 24 hour timeout for subscriptions.
            proxy_read_timeout 86400s;

            # Write timeout, slightly above AppSync's 30s limit
            proxy_send_timeout 35s;
        }

Log output

No response

aws-exports.js

No response

Manual configuration

  Amplify.configure({
    aws_appsync_graphqlEndpoint: endpoint,
    aws_appsync_region: awsRegion,
    aws_appsync_authenticationType: 'AWS_LAMBDA',
    aws_appsync_apiKey: 'null',
  });

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

I believe the fix should look something like this: https://github.com/aws-amplify/amplify-js/compare/main...benvandenberg:amplify-js:feature/appsync-proxy-endpoint

chrisbonifacio commented 2 months ago

Hi @benvandenberg thanks for raising this issue. I'm going to mark it as a feature request for the team to consider.

benvandenberg commented 2 months ago

Thank you @chrisbonifacio . The changes should look something close to https://github.com/aws-amplify/amplify-js/compare/main...benvandenberg:amplify-js:feature/appsync-proxy-endpoint