{"action":"created","issue":{"url":"https://api.github.com/repos/prismagraphql/graphql-yoga/issues/349","repository_url":"https://api.github.com/repos/prismagraphql/graphql-yoga","labels_url":"https://api.github.com/repos/prismagraphql/graphql-yoga/issues/349/labels{/name}","comments_url":"https://api.github.com/repos/prismagraphql/graphql-yoga/issues/349/comments","events_url":"https://api.github.com/repos/prismagraphql/graphql-yoga/issues/349/events","html_url":"https://github.com/prismagraphql/graphql-yoga/issues/349","id":327902695,"node_id":"MDU6SXNzdWUzMjc5MDI2OTU=","number":349,"title":"Custom subscriptions onConnect function not invoked when client connects over web socket for subscriptions","user":{"login":"ekron","id":364735,"node_id":"MDQ6VXNlcjM2NDczNQ==","avatar_url":"https://avatars0.githubusercontent.com/u/364735?v=4","gravatar_id":"","url":"https://api.github.com/users/ekron","html_url":"https://github.com/ekron","followers_url":"https://api.github.com/users/ekron/followers","following_url":"https://api.github.com/users/ekron/following{/other_user}","gists_url":"https://api.github.com/users/ekron/gists{/gist_id}","starred_url":"https://api.github.com/users/ekron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekron/subscriptions","organizations_url":"https://api.github.com/users/ekron/orgs","repos_url":"https://api.github.com/users/ekron/repos","events_url":"https://api.github.com/users/ekron/events{/privacy}","received_events_url":"https://api.github.com/users/ekron/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-05-30T21:17:12Z","updated_at":"2018-05-31T10:09:04Z","closed_at":"2018-05-31T10:09:04Z","author_association":"NONE","body":"Thanks for all your work on graphql-yoga.\r\n\r\nAccording to the [readme](https://github.com/prismagraphql/graphql-yoga#startoptions-options-callback-options-options--void----null-promisevoid) I can add an `onConnect` handler when I create a server.\r\n\r\nE.g.\r\n\r\n```js\r\nconst server = new GraphQLServer({\r\n  ...\r\n  subscriptions: {\r\n    onConnect: () => {\r\n      // here I'd verify the token and look up the user\r\n      // but for example purposes I skip that step.\r\n      return { user: \"me\" }; // should be added to context?\r\n    }\r\n   ...\r\n});\r\n```\r\n\r\nWhen a client connects to the server, the object returned by `onConnect` is added to each subscription resolver's context for that client's ws connection?\r\n\r\nE.g.\r\n\r\n```js\r\n...\r\n  Subscription: {\r\n    counter: {\r\n      subscribe: (parent, args, context) => {\r\n        // user property should be present on context?\r\n        const { pubsub } = context;\r\n        return pubsub.asyncIterator(\"counter\");\r\n      }\r\n...\r\n```\r\n\r\nIn my case, the web socket connection works with Apollo client.\r\n\r\nThe only problem is my custom `onConnect` function is never called. So I cannot add properties to the subscriber resolver context; such as auth tokens passed in by apollo client as `connectionParams`\r\n\r\n```js\r\nconst wsLink = new WebSocketLink({\r\n  uri: 'ws://localhost:4000',\r\n  options: {\r\n    reconnect: true,\r\n    connectionParams: {\r\n      Authorization: \"some token\",\r\n    },\r\n  },\r\n});\r\n```\r\n\r\nI am probably missing something really obvious at my end. If so I apologise and thanks for your patience.\r\n\r\nHere is a complete server example:\r\n\r\n```js\r\nconst { GraphQLServer, PubSub } = require(\"graphql-yoga\");\r\n\r\nconst typeDefs = `\r\n  type Query {\r\n    hello: String!\r\n  }\r\n\r\n  type Counter {\r\n    count: Int!\r\n    countStr: String\r\n  }\r\n\r\n  type Subscription {\r\n    counter: Counter!\r\n  }\r\n`;\r\n\r\nconst resolvers = {\r\n  Query: {\r\n    hello: () => `Hello`\r\n  },\r\n  Counter: {\r\n    countStr: counter => `Current count: ${counter.count}`\r\n  },\r\n  Subscription: {\r\n    counter: {\r\n      subscribe: (parent, args, context) => {\r\n        // user property not present on context; only pubsub and test properties present\r\n        const { pubsub } = context;\r\n        return pubsub.asyncIterator(\"counter\");\r\n      }\r\n    }\r\n  }\r\n};\r\n\r\nconst pubsub = new PubSub();\r\nlet count = 0;\r\nsetInterval(\r\n  () => pubsub.publish(\"counter\", { counter: { count: count++ } }),\r\n  2000\r\n);\r\n\r\nconst server = new GraphQLServer({\r\n  typeDefs,\r\n  resolvers,\r\n  debug: true,\r\n  context: req => ({ pubsub, test: \"aha\" }),\r\n  subscriptions: {\r\n    onConnect: () => {\r\n      // here I'd verify the token and look up the user\r\n      // but for example purposes I skip that step.\r\n      return { user: \"me\" }; // should be added to context?\r\n    }\r\n  }\r\n});\r\n\r\nserver.start(() => console.log(\"Server is running on localhost:4000\"));\r\n```\r\n\r\nThanks for your help with this."},"comment":{"url":"https://api.github.com/repos/prismagraphql/graphql-yoga/issues/comments/393482961","html_url":"https://github.com/prismagraphql/graphql-yoga/issues/349#issuecomment-393482961","issue_url":"https://api.github.com/repos/prismagraphql/graphql-yoga/issues/349","id":393482961,"node_id":"MDEyOklzc3VlQ29tbWVudDM5MzQ4Mjk2MQ==","user":{"login":"ekron","id":364735,"node_id":"MDQ6VXNlcjM2NDczNQ==","avatar_url":"https://avatars0.githubusercontent.com/u/364735?v=4","gravatar_id":"","url":"https://api.github.com/users/ekron","html_url":"https://github.com/ekron","followers_url":"https://api.github.com/users/ekron/followers","following_url":"https://api.github.com/users/ekron/following{/other_user}","gists_url":"https://api.github.com/users/ekron/gists{/gist_id}","starred_url":"https://api.github.com/users/ekron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekron/subscriptions","organizations_url":"https://api.github.com/users/ekron/orgs","repos_url":"https://api.github.com/users/ekron/repos","events_url":"https://api.github.com/users/ekron/events{/privacy}","received_events_url":"https://api.github.com/users/ekron/received_events","type":"User","site_admin":false},"created_at":"2018-05-31T10:09:04Z","updated_at":"2018-05-31T10:09:04Z","author_association":"NONE","body":"Confusion at my end. For anyone else, pass a function to the `context` option. The argument passed to that object will contain the web socket connection data from the client. \r\n\r\ne.g.\r\n\r\n```js\r\n...\r\ncontext: conn => {\r\n    return { pubsub, ...conn.connection.context };\r\n  }\r\n...\r\n```\r\nSetting up a server:\r\n\r\n```js\r\nconst server = new GraphQLServer({\r\n  typeDefs,\r\n  resolvers,\r\n  debug: true,\r\n  context: conn => {\r\n    return { pubsub, ...conn.connection.context };\r\n  }\r\n});\r\n```\r\n\r\nThen in your resolver access the `context` as you would expect:\r\n\r\n```js\r\nsubscribe: (parent, args, context) => {\r\n        // connection's connection data will be present on the context object.\r\n        const { pubsub, somePropertyFromtheClient } = context;\r\n        return pubsub.asyncIterator(\"counter\");\r\n      }\r\n```\r\n"}}
{"actor":{"display_login":"ekron"}}