Subscription not connecting using ApolloServer
I'm trying to get a subscription up and working with ApolloServer (v 2.2.2). I had a setup that all-of-a-sudden just stopped working. When I try to connect to the subscription in graphiql
/Playground
I get the error:
{
"error": "Could not connect to websocket endpoint ws://localhost:4000/graphql. Please check if the endpoint url is correct."
}
As I have rest-endpoints in my app I need to have express but I can't get the minimal example from below running:
import http from 'http';
import { ApolloServer, PubSub } from 'apollo-server-express';
import express from 'express';
const pubsub = new PubSub();
// The DB
const messages = [];
const typeDefs = `
type Query {
messages: [String!]!
}
type Mutation {
addMessage(message: String!): [String!]!
}
type Subscription {
newMessage: String!
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
`;
const resolvers = {
Query: {
messages() {
return messages;
}
},
Mutation: {
addMessage(root, { message }) {
let entry = JSON.stringify({ id: messages.length, message: message });
messages.push(entry);
pubsub.publish('newMessage', { entry: entry });
return messages;
},
},
Subscription: {
newMessage: {
resolve: (message) => {
return message.entry;
},
subscribe: () => pubsub.asyncIterator('newMessage'),
},
},
};
const app = express();
const PORT = 4000;
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
onConnect: () => console.log('Connected to websocket'),
}
});
server.applyMiddleware({ app })
const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);
httpServer.listen(PORT, () => {
console.log(`š Server ready at http://localhost:${PORT}${server.graphqlPath}`)
console.log(`š Subscriptions ready at ws://localhost:${PORT}${server.subscriptionsPath}`)
})
The other endpoints work fine but it is unable to create the WebSocket. As far as I understand it I shouldn't have to use a different server or port (see https://www.ably.io/concepts/websockets). I've tinkered with SubsciptionServer
but this should be handled by installSubscriptionHandlers
(here's the code).
1 answer
-
answered 2018-11-21 23:01
Max Gordon
Not sure what the issue was but after changing computer it works.
I've created an example repo: https://github.com/gforge/subscription_example that works both by itself and with a Docker container.
See also questions close to this topic
-
how can I use different uri in same function
I'm trying to make a download function by url
In HTML there are 3 buttons (download, pause, restart) calls download_file(),pause22(), restart_test() .
They use same variable [req] declared in download_file() which contains a request object.
It works ok If I call only one time.
but The problem is I need to make download lists. so each download_file() needs to use different URL and it would be called at the same time many times by users. also when request is ended need to show a message at the clicked button.
can I reuse functions?
It would be stupid if I make each different functions by url.
how could I distinguish what is clicked?
js
function download_file(event, filename) { req = request({ method: 'GET', uri: fileURL, }); var out = fs.createWriteStream(finalPath); req.pipe(out); req.on('data', function(chunk) { received_bytes += chunk.length; }); req.on('end', function() { subW = test.substring(9, 18).trim(); $("." + subW).text('finished'); endV = 2; }); } //resume function function restart_test() { req = request({ method: 'GET', uri: fileURL }); var out = fs.createWriteStream(finalPath); req.pipe(out); req.on('data', function(chunk) { received_bytes += chunk.length; }); req.on('end', function() { subW = test.substring(9, 18).trim(); $("." + subW).text('finished'); endV = 2; }); } //pause $('#btn-pause').click(function(e) { console.log('pause function called'); req.pause(); });
html
<tr> <td class="test"><a class="checkBtn checkBtn2" onclick="download_file(event, '100mb.bin')">download</a></td> <td><a class="pauseBtn pauseBtn2" id="btn-pause" value="ACTION">pause</a><a class="resumeBtn resumeBtn2" onclick="restart_test();" value="ACTION">restart</a></td> </tr> <tr> <td class="test"><a class="checkBtn checkBtn2" onclick="download_file(event, '1000mb.bin')">download</a></td> <td><a class="pauseBtn pauseBtn2" id="btn-pause" value="ACTION">pause</a><a class="resumeBtn resumeBtn2" onclick="restart_test();" value="ACTION">restart</a></td> </tr>
- How to add a new object to Observer type - javascprit
-
ngx-quill issue with Language tool extension
I am using ngx-quill-editor as a rich text editor for my angular application. I am not getting Value from quill as expected while using Language tool chrome extension. It works fine otherwise.
I didn't find any issue raised for support of quill editor with Language tool.
The value I get from quill editor while using Language tool is like this: ''
When a user type 'Hello world' in editor, then I should get a value like '
Hello world
'. But I am not getting value as expected. -
What is the correct syntax to pass variable into mutation in graphql
I have a react native app.
What is the correct syntax in graphql to pass variable into customerCreate?
const url = 'https://xxxx.myshopify.com/api/graphql'; const query = ` var variable = { "input": { "email": "test@test.com", "password": "pass" } } mutation customerCreate($input: CustomerCreateInput!) { customerCreate(input: $input) { userErrors { field message } customer { id } } } `; fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: query }), }) .then(res => res.json()) .then(res => console.log(res.data)); .catch(err => { console.log('-- gql err --') console.error(err); })
-
Gatsby: set an image background through frontmatter, GraphQl and Styled-components
I know this problem sounds a bit complex but it's not.
I'll try my best to explain it in a simple way:- I'm making a list of blog posts for the homepage of my Gatsby website.
The list is made of "boxes", every box that links to a post has a background-image.
I pass this background-image to a styled-component, it gets the image from a prop value that I inserted in the main < div > element (you'll find the example bellow).
It works fine, till I try use an image from my local folder under src (instead of using an online link that I simply putted on frontmatter).
Here's what I did in the past, and worked:
I put the url of the image on the frontmatter of the markdown file:--- slug: "/post/my-post" [...] imghero: "https:/path/to/image-online.jpg" ---
Then query it with graphql:
const LISTING_QUERY = graphql` query BlogPostListing { allMarkdownRemark(limit: 10, sort: { order: DESC, fields: [frontmatter___date] }) { edges { node { excerpt frontmatter { title slug date(formatString: "MMMM DD, YYYY") imghero } } } } } `
After that I insert the {node.frontmatter.imghero} it on a prop on the main div:
const Listing = () => ( <StaticQuery query={LISTING_QUERY} render={({allMarkdownRemark}) => ( allMarkdownRemark.edges.map(({node}) => ( <Article img_background={node.frontmatter.imghero} key={node.frontmatter.slug}> [... etc ...] </Article> )) )} /> ) export default Listing
And finally I call that img_background prop in the styled-component:
const Article = styled.article` background-image: url(${props => props.img_background};); [... etc ...] `
This method works.
Now I want to get the image from my "images" folder and not from a random url.
- I installed gatsby-remark-images
- Set it on gatsby-config.js and put the path of some image on frontmatter.
- Test everything with http://localhost:8000/___graphql (and worked)
Insert the additional query throught graphql:
[...] frontmatter { date(formatString: "DD MMMM, YYYY") title imghero hero { childImageSharp{ fluid(maxWidth: 630) { ...GatsbyImageSharpSizes } } } [...]
I modify the node on the component with the new path:
<Article img_background={node.frontmatter.hero.childImageSharp.fluid} [...]> [...] </Article>
Gatsby Develop compiles fine.
But then my homepage is completely white.
And the console of the browser says that node.frontmatter.hero is "null". I don't know that else to do.Thanks for the help.
-
Generating data navigation automatically from GraphQL Schema
I am trying to parse the Schema & AST of a given GraphQL endpoint in order to create auto-generated navigation (according to the parsed schema) for my data.
I tried looking for a solution for public projects but couldn't find any. If anyone has any suggestion / could refer me to a starting point it could be amazing.
-
Need to find the error with connecting subscription with schema stitching
I am using apollo-server-express for graphql back-end. I am going to process only mutations there, but I want to redirect query and subscription on hasura by means of schema stitching with introspection. Queries through apollo-server to hasura are working fine and returning the expected data.
But subscriptions are not working and I am getting this error: " Expected Iterable, but did not find one for field subscription_root.users".
And besides, server hasura is receiving events:
But apollo-server resents the answer from hasura. It is not the first day I suffer with this and I can not understand what the problem is.
In the editor hasura subscriptions work.
If you need any additional info, I will gladly provide it to you.
import { introspectSchema, makeExecutableSchema, makeRemoteExecutableSchema, mergeSchemas, transformSchema, FilterRootFields } from 'graphql-tools'; import { HttpLink } from 'apollo-link-http'; import nodeFetch from 'node-fetch'; import { resolvers } from './resolvers'; import { hasRoleResolver } from './directives'; import { typeDefs } from './types'; import { WebSocketLink } from 'apollo-link-ws'; import { split } from 'apollo-link'; import { getMainDefinition } from 'apollo-utilities'; import { SubscriptionClient } from 'subscriptions-transport-ws'; import * as ws from 'ws'; import { OperationTypeNode } from 'graphql'; interface IDefinitionsParams { operation?: OperationTypeNode, kind: 'OperationDefinition' | 'FragmentDefinition' } const wsurl = 'ws://graphql-engine:8080/v1alpha1/graphql'; const getWsClient = function (wsurl: string) { const client = new SubscriptionClient(wsurl, { reconnect: true, lazy: true }, ws); return client; }; const wsLink = new WebSocketLink(getWsClient(wsurl)); const createRemoteSchema = async () => { const httpLink = new HttpLink({ uri: 'http://graphql-engine:8080/v1alpha1/graphql', fetch: (nodeFetch as any) }); const link = split( ({ query }) => { const { kind, operation }: IDefinitionsParams = getMainDefinition(query); console.log('kind = ', kind, 'operation = ', operation); return kind === 'OperationDefinition' && operation === 'subscription'; }, wsLink, httpLink, ); const remoteSchema = await introspectSchema(link); const remoteExecutableSchema = makeRemoteExecutableSchema({ link, schema: remoteSchema }); const renamedSchema = transformSchema( remoteExecutableSchema, [ new FilterRootFields((operation, fieldName) => { return (operation === 'Mutation') ? false : true; // && fieldName === 'password' }) ] ); return renamedSchema; }; export const createNewSchema = async () => { const hasuraExecutableSchema = await createRemoteSchema(); const apolloSchema = makeExecutableSchema({ typeDefs, resolvers, directiveResolvers: { hasRole: hasRoleResolver } }); return mergeSchemas({ schemas: [ hasuraExecutableSchema, apolloSchema ] }); };
-
'error creating handler' GraphQL Apollo Server Not Working on Lambda
I am attempting to deploy my Apollo GraphQL server to Lambda as a demo.
I am using UP to deploy to AWS, the function creates fine and the upload seems to work, however when visiting the resulting URL I always get a
{"message": "Internal server error"}
When inspecting the logs, I see the following errors:
"src/app.js: line 1: //: Is a directory"
"src/app.js: line 2: syntax error near unexpected token
('"`'src/app.js: line 2: `const { ApolloServer } = require('apollo-server-lambda');'
error creating handler: waiting for http://127.0.0.1:39907 to be in listening state: timed out after 15s
The code for my app.js is as follows:
const { ApolloServer } = require('apollo-server-lambda'); const typeDefs = require('./schema'); const { createStore } = require('./utils'); const LaunchAPI = require('./datasources/launch'); const UserAPI = require('./datasources/user'); const store = createStore(); const resolvers = require('./resolvers'); const server = new ApolloServer({ typeDefs, resolvers, engine: { apiKey: process.env.ENGINE_API_KEY }, dataSources: () => ({ launchAPI: new LaunchAPI(), userAPI: new UserAPI({ store }), }) }); exports.graphqlHandler = server.createHandler();
Does anyone have any idea as to the cause? or how I can diagnose further? as I'm a bit lost. To add, the app works on localhost just fine
-
Getting Cannot read property 'args' of undefined when trying to stitch schema's with apollo server
There seem to be some similar questions but none at the same point as where I get the error and none with the 'args' of undefined.
I've gotten it to work to have multiple other graphql apis and merge them. Just mergin them is going well but when I try to make a stitch I get the error shown below:
"errors": [ { "message": "Cannot read property 'args' of undefined", "locations": [ { "line": 9, "column": 9 } ], "path": [ "flows", "edges", 0, "node", "sourceAddresses" ], "extensions": { "code": "INTERNAL_SERVER_ERROR", "exception": { "stacktrace": [ "TypeError: Cannot read property 'args' of undefined", " at /opt/node_modules/graphql-tools/src/transforms/AddArgumentsAsVariables.ts:103:15", " at Array.forEach (<anonymous>)", " at /opt/node_modules/graphql-tools/src/transforms/AddArgumentsAsVariables.ts:95:39", " at Array.map (<anonymous>)", " at addVariablesToRootField (/opt/node_modules/graphql-tools/src/transforms/AddArgumentsAsVariables.ts:66:36)", " at AddArgumentsAsVariablesTransform.transformRequest (/opt/node_modules/graphql-tools/src/transforms/AddArgumentsAsVariables.ts:31:11)", " at /opt/node_modules/graphql-tools/src/transforms/transforms.ts:24:21", " at Array.reduce (<anonymous>)", " at Object.applyRequestTransforms (/opt/node_modules/graphql-tools/src/transforms/transforms.ts:21:21)", " at /opt/node_modules/graphql-tools/src/stitching/delegateToSchema.ts:90:28" ] } } }
]
I've got a schemaRetriever service that retrieves the schemas from 3 GraphQL Api's. For now I'm trying to get 1 stitch working so the code isn't really 'nice' at the moment.
Here is the piece of code where I try to get a stitch going:
const aSchema = await this.schemaRetrieverService.retrieveASchema(); const housesSchema = await this.schemaRetrieverService.retrieveHousesSchema(); const addressSchema = await this.schemaRetrieverService.retrieveAddressSchema(); return mergeSchemas({ schemas: [ aSchema, housesSchema, addressSchema, ` extend type Houses { houseAddresses: Addresses } extend type Addresses { houses: Houses } type Query { addressByHouseId(id: ID!): Addresses } ` ], resolvers: { Houses: { houseeAddresses: { fragment: `... on Houses { id }`, resolve(house, args, context, info) { return info.mergeInfo.delegateToSchema({ schema: addressSchema, operation: 'query', fieldName: 'addressByHouseId', args: { id: house.houseAddress, }, context, info, }); }, }, }, }, });
I've verifies that 'house.houseAddress' contains the correct ID that is needed and I keep getting the same error although I'm putting a valid ID in the args variable. Am I missing something small here? or big? If someone could give me a pointer I would be so grateful.
Many thanks in advance and if any information is missing please let me know I'll try to add all necessary info.
-
Issue setting up subscription with GraphQL
Good day:
I"m trying to setup my graphql server for a subscription. This is my schema.js
const ChatCreatedSubscription = new GraphQLObjectType({ name: "ChatCreated", fields: () => ({ chatCreated: { subscribe: () => pubsub.asyncIterator(CONSTANTS.Websocket.CHANNEL_CONNECT_CUSTOMER) } }) }); const ChatConnectedSubscription = { chatConnected: { subscribe: withFilter( (_, args) => pubsub.asyncIterator(`${args.id}`), (payload, variables) => payload.chatConnect.id === variables.id, ) } } const subscriptionType = new GraphQLObjectType({ name: "Subscription", fields: () => ({ chatCreated: ChatCreatedSubscription, chatConnected: ChatConnectedSubscription }) }); const schema = new GraphQLSchema({ subscription: subscriptionType });
However, I'm getting this error when I try to run my subscription server:
ERROR introspecting schema: [ { "message": "The type of Subscription.chatCreated must be Output Type but got: undefined." }, { "message": "The type of Subscription.chatConnected must be Output Type but got: undefined." } ]
-
AWS Appsync complex subscription arguments
I'm currently working on an messaging app and want to create a global subscription just to demonstrate what I want to achieve Suppose there is a mutation like sendMessage that contains senderId and Members just for example like :-
mutation sendMessage(senderId :String!,members:[String]){ response }
This mutation is used to send message to user the real example is different and complex so I'm asking with small example lets run a mutation with the following values like :-
mutation sendMessage(senderId :"A",members:["A","B","C"]){ response }
My question - Is it possible to get the subscription only when the members contain "B" in members array something like this :-
subscribeToSendMessage(member:["B"]): message aws_subscribe(mutations: ["sendMessage"])
-
Generate Subscription with arguments in AWS AppSync with GraphQL Transform
Iām currently using GraphQL transform lib to generate all my schema. I have a model defined like this:
type Feedback @model { id: ID! event: Event! @connection(name: "EventFeedbacks") submittedDate: AWSDateTime! }
and the auto-generated subscription schema is like this:
type Subscription { onCreateFeedback: Feedback @aws_subscribe(mutations: ["createFeedback"]) }
I would like to have an argument for the subscription so that I can subscribe to that event only, like this:
type Subscription { onCreateFeedback(eventId: ID): Feedback @aws_subscribe(mutations: ["createFeedback"]) }
What do I need to do to get this subscription auto generated? Thanks!