The GraphQL federation subscription type configuration is not applied on subgraphs

Branch/Environment/Version

  • Branch/Version: 5.2.4
  • Environment: Docker

Describe the bug
The GraphQL federation subscription type configuration is not applied on subgraphs.

{
  ...,
  "graphql": {
    ...,
    "supergraph": {
      ...,
      "subgraphs": [
        ...,
        {
          ...,
          "subscription_type": "graphql-transport-ws"
        }
      ]
    }
  }
}

Reproduction steps
Steps to reproduce the behaviour:

  1. Add a graphql supergraph api
{
  "name": "Public API",
  "api_id": "public-api",
  "org_id": "default",
  "definition": {
    "location": "header",
    "key": "version"
  },
  "use_keyless": true,
  "version_data": {
    "not_versioned": true,
    "versions": {
      "Default": {
        "name": "Default",
        "use_extended_paths": true
      }
    }
  },
  "proxy": {
    "listen_path": "/public/graphql"
  },
  "enable_context_vars": true,
  "graphql": {
    "version": "2",
    "enabled": true,
    "playground": {
      "enabled": true,
      "path": "/playground"
    },
    "execution_mode": "supergraph",
    "supergraph": {
      "global_headers": {
        "Authorization": "$tyk_context.headers_Authorization"
      },
      "subgraphs": [
        {
          "url": "http://test/graphql",
          "subscription_type": "graphql-transport-ws",
          "sdl": "type Test { id: String } type Query { tests: [Test!]! } type Subscription { tests: Test! }"
        }
      ],
      "merged_sdl": "type Test { id: String } type Query { tests: [Test!]! } type Subscription { tests: Test! }"
    },
    "schema": "type Test { id: String } type Query { tests: [Test!]! } type Subscription { tests: Test! }"
  }
}
  1. Execute a the GraphQL tests query or subscription over WebSocket using graphql-transport-ws protocol on http://localhost:8080/public/graphql

Actual behaviour
The subgraph upstream initial WebSocket Upgrade HTTP Request is using graphql-ws protocol instead of configured graphql-transport-ws protocol

Hypertext Transfer Protocol
    GET /graphql HTTP/1.1
    Host: test
    User-Agent: Go-http-client/1.1
    Accept-Encoding: gzip
    Connection: Upgrade
    Sec-Websocket-Key: XXXXX
    Sec-Websocket-Protocol: graphql-ws
    Sec-Websocket-Version: 13
    Upgrade: websocket
    X-Forwarded-For:
    X-Tyk-Parent-Request-Id: c62b1f50-be71-48e6-8f78-f1bef7532b18

Expected behaviour
The subgraph upstream initial WebSocket Upgrade HTTP Request is using graphql-transport-ws protocol

Hypertext Transfer Protocol
    GET /graphql HTTP/1.1
    Host: test
    User-Agent: Go-http-client/1.1
    Accept-Encoding: gzip
    Connection: Upgrade
    Sec-Websocket-Key: XXXXX
    Sec-Websocket-Protocol: graphql-transport-ws
    Sec-Websocket-Version: 13
    Upgrade: websocket
    X-Forwarded-For:
    X-Tyk-Parent-Request-Id: c62b1f50-be71-48e6-8f78-f1bef7532b18

Screenshots/Video
NA

Logs (debug mode or log file):

tyk-gateway-1  | time="XXXX" level=error msg="subscription.Handle.executeSubscription()" error="failed to get reader: received close frame: status = StatusCode(4406) and reason = \"Subprotocol not acceptable\". retrying in 8s"

Configuration (tyk config file):

{
  "log_level": "debug" ,
  "listen_port": 8080,
  "secret": "352d20ee67be67f6340b4c0605b044b7",
  "template_path": "/opt/tyk-gateway/templates",
  "tyk_js_path": "/opt/tyk-gateway/js/tyk.js",
  "middleware_path": "/opt/tyk-gateway/middleware",
  "use_db_app_configs": false,
  "app_path": "/opt/tyk-gateway/apps/",
  "storage": {
    "type": "redis",
    "host": "localhost",
    "port": 6379,
    "username": "",
    "password": "",
    "database": 0,
    "optimisation_max_idle": 2000,
    "optimisation_max_active": 4000
  },
  "enable_analytics": false,
  "analytics_config": {
    "type": "",
    "ignored_ips": []
  },
  "health_check": {
    "enable_health_checks": false,
    "health_check_value_timeouts": 60
  },
  "enable_non_transactional_rate_limiter": true,
  "enable_sentinel_rate_limiter": false,
  "enable_redis_rolling_limiter": false,
  "allow_master_keys": false,
  "policies": {
    "policy_source": "file",
    "policy_record_name": "/opt/tyk-gateway/policies/policies.json"
  },
  "hash_keys": true,
  "close_connections": false,
  "http_server_options": {
    "enable_websockets": true
  },
  "allow_insecure_configs": false,
  "coprocess_options": {
    "enable_coprocess": true,
    "coprocess_grpc_server": ""
  },
  "enable_bundle_downloader": true,
  "bundle_base_url": "",
  "global_session_lifetime": 100,
  "force_global_session_lifetime": false,
  "max_idle_connections_per_host": 500,
  "enable_jsvm": false
}

Additional context
I hope it is a wrong configuration from my side or it will help you to improve this amazing product.

@vgillesultra Thanks for reporting this and welcome to the community :partying_face:

We will check this out and report back

Hey @vgillesultra

at first glance this looks like it’s your upstream actually not being able to support graphql-transport-ws. The close frame you pasted is from upstream, not from the GW.

The community has made it a bit confusing when it comes to Websocket protocols for GQL subscriptions and the naming is misleading. Here’s a link to our docs you can find links to GH repos of the protocols themselves. Please double check which one your upstream is actually using and let us know.

Our upstream only accept the graphql-transport-ws sub-protocol. We are using the graphql-ws node package.

The frame

Hypertext Transfer Protocol
    GET /graphql HTTP/1.1
    Host: test
    User-Agent: Go-http-client/1.1
    Accept-Encoding: gzip
    Connection: Upgrade
    Sec-Websocket-Key: XXXXX
    Sec-Websocket-Protocol: graphql-ws
    Sec-Websocket-Version: 13
    Upgrade: websocket
    X-Forwarded-For:
    X-Tyk-Parent-Request-Id: c62b1f50-be71-48e6-8f78-f1bef7532b18

is the initial GET sended by tyk-gateway.

Here it is the frame without tyk-gateway:

Hypertext Transfer Protocol
    GET /graphql HTTP/1.1
    Host: test
    Connection: Upgrade
    Pragma: no-cache
    Cache-Control: no-cache
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
    Upgrade: websocket
    Origin: null
    Sec-WebSocket-Version: 13
    Accept-Encoding: gzip, deflate, br
    Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
    Sec-WebSocket-Key: XXXX
    Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
    Sec-WebSocket-Protocol: graphql-transport-ws
``