Hive Gateway subscriptons not working
Issue workflow progress
Progress of the issue based on the Contributor Workflow
- [ ] 1. The issue provides a reproduction available on Github, Stackblitz or CodeSandbox
Make sure to fork this template and run
yarn generatein the terminal.Please make sure Mesh package versions under
package.jsonmatches yours.
- [ ] 2. A failing test has been provided
- [ ] 3. A local solution has been provided
- [ ] 4. A pull request is pending review
Describe the bug
Graphql subscriptions do not work. If i try to run the subscription through GraphiQL, the response is 404
The OpenTelemetry logs are as follows:
{
resource: {
attributes: {
'service.name': 'Gateway',
'telemetry.sdk.language': 'nodejs',
'telemetry.sdk.name': 'opentelemetry',
'telemetry.sdk.version': '1.25.1',
'process.pid': 6,
'process.executable.name': 'node',
'process.executable.path': '/usr/local/bin/node',
'process.command_args': [ '/usr/local/bin/node', '/serve/bin.mjs', 'supergraph' ],
'process.runtime.version': '22.8.0',
'process.runtime.name': 'nodejs',
'process.runtime.description': 'Node.js',
'process.command': '/serve/bin.mjs',
'process.owner': 'node',
'host.name': 'hive-gateway-external-66984f7fd-5w5hb',
'host.arch': 'amd64'
}
},
instrumentationScope: { name: 'gateway', version: undefined, schemaUrl: undefined },
traceId: '5a5a8607eaa73a972e9cf13cb7f104e7',
parentId: undefined,
traceState: undefined,
name: 'GET /gateway/graphql',
id: 'a2a1816dfb7b25ec',
kind: 1,
timestamp: 1726128168069000,
duration: 2460.951,
attributes: {
'http.method': 'GET',
'http.url': 'http://localhost/gateway/graphql?query=subscription+test%7BinventoryEvents%7B...on+CabinetStatusChangedEvent%7BeventId+cabinetId+previousStatusId+currentStatusId%7D...on+CageStatusChangedEvent%7BeventId+cageId+previousStatusId+currentStatusId%7D%7D%7D&operationName=test&extensions=%7B%7D',
'http.route': '/gateway/graphql',
'http.scheme': 'http:',
'net.host.name': 'localhost',
'http.host': 'localhost',
'http.client_ip': '10.249.0.4',
'http.user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:130.0) Gecko/20100101 Firefox/130.0',
'http.status_code': 404
},
status: { code: 2, message: 'Not Found' },
events: [],
links: []
}
Queries for the same subgraph that provides this subscription work correctly.
Subscribing directly to subgraph works correctly
**To Reproduce** Steps to reproduce the behavior:
Run Hive Gateway with at least one subgraph implementing subscriptions using websocket transport.
Configure Hive Gateway with endpoint:
gateway.config.ts: | import {defineConfig, type WSTransportOptions, createStdoutExporter} from '@graphql-hive/gateway'
export const gatewayConfig = defineConfig({
transportEntries: {
// use "*.http" to apply options to all subgraphs with HTTP
'*.http': {
options: {
subscriptions: {
kind: 'ws',
location: '/graphql'
} satisfies WSTransportOptions
}
}
},
openTelemetry: {
exporters: [
// A simple output to the console.
// You can add more exporters here, please see documentation below for more examples.
createStdoutExporter()
],
spans: {
http: true, // Whether to track the HTTP request/response
graphqlParse: true, // Whether to track the GraphQL parse phase
graphqlValidate: true, // Whether to track the GraphQL validate phase
graphqlExecute: true, // Whether to track the GraphQL execute phase
subgraphExecute: true, // Whether to track the subgraph execution phase
upstreamFetch: true // Whether to track the upstream HTTP requests
}
}
})
**Expected behavior**
Subscriptions work correctly
**Environment:**
- OS:
- Hive Gateway Docker
Could you give more details about your subgraphs? Do they use graphql-ws protocol? Or maybe they use the legacy subscriptions-transport-ws?
There is only one subgraph serving subscriptions. It is based on graphql-ws protocol
https://docs.spring.io/spring-graphql/reference/transports.html#server.transports.websocket
But it seems like the gateway is not even trying to call it
Have you tried to make the HTTP request with curl or some other http client?
I tried making a request with Postman GraphQL client.
There is says that gateway responded with incorrect response code 200 instead of 101
Here are the logs from this request
{ resource: { attributes: { 'service.name': 'Gateway', 'telemetry.sdk.language': 'nodejs', 'telemetry.sdk.name': 'opentelemetry', 'telemetry.sdk.version': '1.25.1', 'process.pid': 6, 'process.executable.name': 'node', 'process.executable.path': '/usr/local/bin/node', 'process.command_args': [ '/usr/local/bin/node', '/serve/bin.mjs', 'supergraph' ], 'process.runtime.version': '22.8.0', 'process.runtime.name': 'nodejs', 'process.runtime.description': 'Node.js', 'process.command': '/serve/bin.mjs', 'process.owner': 'node', 'host.name': 'hive-gateway-external-7664cc5d55-89g5m', 'host.arch': 'amd64' } }, instrumentationScope: { name: 'gateway', version: undefined, schemaUrl: undefined }, traceId: '4fce12dacd20a8c23d04f77f0cdddbf9', parentId: undefined, traceState: undefined, name: 'GET /gateway/graphql', id: 'c16e61a8e3b4aaaf', kind: 1, timestamp: 1726157965615000, duration: 732.977, attributes: { 'http.method': 'GET', 'http.url': 'http://localhost/gateway/graphql', 'http.route': '/gateway/graphql', 'http.scheme': 'http:', 'net.host.name': 'localhost', 'http.host': 'localhost', 'http.client_ip': '10.249.0.4', 'http.user_agent': 'PostmanClient/undefined (AppId=6217ee3f-4ef9-4f3d-b10a-c0582107b1ea)', 'http.status_code': 200 }, status: { code: 1, message: undefined }, events: [], links: [] }
Can you give me an example of correct curl for querying subscription on gateway?
curl 'http://localhost:4000/graphql' \
-H 'accept: text/event-stream' \
-H 'content-type: application/json' \
--data-raw '{"query":"subscription OnProductPriceChanged { productPriceChanged { name price reviews { score } } }","operationName":"OnProductPriceChanged"}'
You can initiate an SSE connection as in here with curl.
Regarding the error in the screenshots you shared above; In there, you are trying to connect the gateway via WebSockets not SSE. We only support the actively developed graphql-ws only not deprecated subscriptions-transport-ws . I am not sure which one Postman uses there.
Hi, I tried forming the request like in the curl you described. This resulted in error:
event: next
data: {"errors":[{"message":"Cannot find package '@graphql-mesh/transport-ws' imported from /node_modules/.chunk/createGatewayRuntime-DfdVdZl2.mjs","locations":[{"line":1,"column":20}],"path":["inventoryEvents"]}]}
event: complete
data:
And in the logs:
[2024-09-13T09:21:43.876Z] DEBUG vdc-inventory-service - 430ed7d622f261c84c120254f2868472 subgraph-execute {
query: 'subscription test2{inventoryEvents{__typename ...on CabinetStatusChangedEvent{eventId}}}',
variables: {}
}
[2024-09-13T09:21:43.876Z] DEBUG Loading transport "ws" for subgraph vdc-inventory-service
[2024-09-13T09:21:43.877Z] HOOKS Trying default resolve for "@graphql-mesh/transport-ws"
[2024-09-13T09:21:43.879Z] DEBUG Processing GraphQL Parameters done.
[2024-09-13T09:21:43.878Z] HOOKS Trying default resolve for "@graphql-mesh/transport-ws" failed; trying alternatives
[2024-09-13T09:21:43.878Z] HOOKS Trying "@graphql-mesh/transport-ws.ts"
This likely means two things:
- The docker image is missing the transport-ws package
- The GraphiQL provided with the Gateway is not compatible with how the Gateway handles subscriptions