When I tried to run a subscription using the cURL
command, it always send the response with null
data. Is there any way to keep returning the correct responses according to the event changes?
I used the following js code to run the GraphQL server.
const { createServer } = require("http");
const express = require("express");
const { execute, subscribe } = require("graphql");
const { ApolloServer, gql } = require("apollo-server-express");
const { PubSub } = require("graphql-subscriptions");
const { SubscriptionServer } = require("subscriptions-transport-ws");
const { makeExecutableSchema } = require("@graphql-tools/schema");
const { withFilter } = require("graphql-subscriptions");
(async () => {
const pubsub = new PubSub();
const app = express();
const httpServer = createServer(app);
const typeDefs = gql`
type Query {
viewMessages: [Message!]
}
type Mutation {
sendMessage(params: DataInput): Message!
}
type Subscription {
receiveMessage(content: String): Message
}
type Message {
id: ID!
name: String!
content: String
}
input DataInput {
name: String
content: String
}
`;
let messages = []
const resolvers = {
Query: {
viewMessages() {
return messages;
},
},
Mutation: {
sendMessage: (parent, { params }) => {
params.id = messages.length;
var new_message = params;
messages.push(new_message);
pubsub.publish("MessageService", {receiveMessage: new_message});
return new_message;
},
},
Subscription: {
receiveMessage: {
subscribe: withFilter(
() => pubsub.asyncIterator(["MessageService"]),
(payload, variables) => {return (payload.receiveMessage.content === variables.content)},
),
},
},
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const server = new ApolloServer({
schema,
});
await server.start();
server.applyMiddleware({ app });
SubscriptionServer.create(
{ schema, execute, subscribe },
{ server: httpServer, path: '/graphql' }
);
const PORT = 4000;
httpServer.listen(PORT, () => {
console.log(
`🚀 Query endpoint ready at http://localhost:${PORT}${server.graphqlPath}`
);
console.log(
`🚀 Subscription endpoint ready at ws://localhost:${PORT}${server.graphqlPath}`
);
});
})();
I used the following cURL
command to run the the subscription query: subscription { receiveMessage { id name } }
curl 'http://localhost:4000/graphql' -H 'Content-Type: application/json' -H 'Connection: keep-alive' -d '{"query":"subscription { receiveMessage { id name } }"}'
The response for the cURL
command is as follows.
{"data": {"receiveMessage": null}}
What I need to do is keep getting responses from a subscription using a cURL
command, while running mutations parallelly. Can this be done? If it is, how do I write a cURL
command for that?
*** For query and mutations, the cURL
commands are working properly.
I'm not certain you can run subscriptons through curl.
Even though curl does support a pretty good list of protocol, you won't be able to get your subscriptions through http (that is : the client sends a request and the server sends the reply) while subscriptions (the server notifies the client when an event occurs) aren't suitable for http.