Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AppSync subscriptions using Private API / VPC endpoints #12517

Open
2 tasks
Ahlaee opened this issue Nov 6, 2023 · 3 comments
Open
2 tasks

AppSync subscriptions using Private API / VPC endpoints #12517

Ahlaee opened this issue Nov 6, 2023 · 3 comments
Labels
feature-request Request a new feature GraphQL Related to GraphQL API issues V5

Comments

@Ahlaee
Copy link

Ahlaee commented Nov 6, 2023

Is this related to a new or existing framework?

No response

Is this related to a new or existing API?

GraphQL API

Is this related to another service?

AppSync

Describe the feature you'd like to request

I would like to be able to use GraphQL subscriptions when Private API is enabled on AWS AppSync. I'm not sure if the current amplify-js behavior is an intended omission or a buggy behavior.

Current behavior

Using VPC endpoints with AppSync requires using a hostname of the form: {vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com when connecting on the network level.

For AppSync to be able to identify the API backend when sending the request to the VPC endpoint one has to pass a host header like this: {"host": "{api_url_identifier}.appsync-api.{region}.amazonaws.com"}

amplify-js has the possibility of passing "graphql_headers" as an option to GraphQLAPI.graphql(). Passing these "graphql_headers" works with queries and mutations, but not with subscriptions. Subscriptions result in a 404 error:
"Error: Unexpected server response: 404 at ClientRequest"

Expected behavior

On the command line I can connect to a private AppSync subscription like this using the VPC endpoint:

header=`echo '{"host":"{api_url_identifier}.appsync-api.{region}.amazonaws.com","x-api-key":"da2-{xxxxxxxxxxxxxxxxxxxxxxxxxx}"}' | base64 -w0`
wscat -H "X-AppSync-Domain:{api_url_identifier}.appsync-realtime-api.{region}.amazonaws.com" -p 13 -s graphql-ws -c "wss://{vpc_endpoint_id}-{endpoint_dns_identifier}.appsync-api.{region}.vpce.amazonaws.com/graphql?header=$header&payload=e30="

The host is encoded in the header parameter which AppSync uses to identify the correct API backend.

Looking into the source code when using the AWSAppSyncRealTimeProvider the "host" variable which is later encoded is set exclusively by appSyncGraphqlEndpoint, which is set through the API config aws_appsync_graphqlEndpoint and which is the VPC endpoint in this case:

const { host } = url.parse(appSyncGraphqlEndpoint ?? '');

There is no alternative to using the VPC endpoint as the host parameter.

Using queries and mutations the graphql_headers seem to be attached correctly so that AppSync can process the request:

Describe the solution you'd like

I would like to have graphql_headers passed to AppSync subscriptions encoded into the header parameter for the websocket connection in order to use GraphQL subscriptions on AppSync Private APIs.

Describe alternatives you've considered

Nothing to mention here.

Additional context

Using
amplify-js 5.3.11
nodejs v20.3.1
ws 8.14.2

Is this something that you'd be interested in working on?

  • 👋 I may be able to implement this feature request
  • ⚠️ This feature might incur a breaking change
@Ahlaee Ahlaee added the pending-triage Issue is pending triage label Nov 6, 2023
@chrisbonifacio chrisbonifacio added GraphQL Related to GraphQL API issues feature-request Request a new feature labels Nov 6, 2023
@cwomack
Copy link
Contributor

cwomack commented Nov 8, 2023

Hello, @Ahlaee 👋. We've marked this as a feature request for now due to the encoding of AppSync subscriptions into headers not being supported out of the box. The detailed use case/context is appreciated and I'll review this with our team.

@cwomack cwomack removed the pending-triage Issue is pending triage label Nov 8, 2023
@Ahlaee
Copy link
Author

Ahlaee commented Nov 14, 2023

Hi @cwomack 👋. Thank you for the fast response. The use case wouldn't be an extraordinary one. We would like to use the full GraphQL feature set in an regulated environment without public exposure of data endpoints. If supporting AppSync subscriptions on an Private API seems to be an unusual request it's ok leaving it as it is. We can look into other event based solutions. I was only wondering why the support was missing in the first place.

@nadetastic nadetastic added the V5 label Jan 23, 2024
@ronkoaveone
Copy link

Hey guys, just a heads up, this is still a really big blocker to using WebSocket connections in a private AppSync. The only way to get a AppSync subscription to work to a private AppSync API is to send either the host or x-appsync-domain with the wss:// request and the WebSocket API in browsers does not allow adding custom headers. The AppSync service does not acknowledge the encoded 'host' property in the base64 encoded 'header' query string. It ignores it.

The only solution I have been able to engineer is to add an Apache server with mod_proxy in front of the VPC Endpoint to AppSync which injects the x-appsync-domain header into the request (since as mentioned above, custom headers cannot be added via JavaScript since the WebSocket API does not support adding custom headers in a browser).

RequestHeader set x-appsync-domain "f43xwyq5bfenvdhrn6aq7u6wyu.appsync-realtime-api.us-east-1.amazonaws.com"

Having to add a whole new infra like apache in containers to manage and scale a serverless app is an aweful solution. The ProxyPass and x-appsync-domain above have to be maintained and deployed with different values to every environment for each of our AppSync APIs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request a new feature GraphQL Related to GraphQL API issues V5
Projects
None yet
Development

No branches or pull requests

5 participants