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:
https://github.com/aws-amplify/amplify-js/blob/c3a06153e3ffe05dd65485a22b1f99aabe9b3d83/packages/pubsub/src/Providers/AWSAppSyncRealTimeProvider/index.ts#L918
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:
https://github.com/aws-amplify/amplify-js/blob/c3a06153e3ffe05dd65485a22b1f99aabe9b3d83/packages/api-graphql/src/internals/InternalGraphQLAPI.ts#L286
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?
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:
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:
https://github.com/aws-amplify/amplify-js/blob/c3a06153e3ffe05dd65485a22b1f99aabe9b3d83/packages/pubsub/src/Providers/AWSAppSyncRealTimeProvider/index.ts#L918
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:
https://github.com/aws-amplify/amplify-js/blob/c3a06153e3ffe05dd65485a22b1f99aabe9b3d83/packages/api-graphql/src/internals/InternalGraphQLAPI.ts#L286
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?