I'm new in GraphQL. When I copied this code from Apollo GraphQL docs (and just add one more line for console.log error), I have this issue. Please let me know how to fix it.
const { ApolloServer, gql } = require('apollo-server-express');
const express = require('express');
const typeDefs = gql`
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
const books = [
{
title: 'The Awakening',
author: 'Kate Chopin',
},
{
title: 'City of Glass',
author: 'Paul Auster',
},
];
const resolvers = {
Query: {
books: () => books,
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
formatError: (err) => console.log(err), // <-- only add 1 more line
});
(async () => {
const app = express();
await server.start();
server.applyMiddleware({ app });
app.listen(4000);
})();
And here is my package.json
"dependencies": {
"apollo-server-express": "^3.6.3",
"express": "^4.17.2",
"graphql": "^16.3.0"
}
Then, when I open graphql studio playground at http://localhost:4000/graphql -> click on Query your server -> I got this error on terminal
[ValidationError: Cannot query field "_service" on type "Query".] {
locations: [ { line: 2, column: 9 } ],
path: undefined,
extensions: {
code: 'GRAPHQL_VALIDATION_FAILED',
exception: { stacktrace: [Array] }
}
}```
I have checked again and this is an error from inside GrapqhQL Studio and it was fixed now.
Related
I setup a graphql server and client by Apollo in nodejs. The server will serve one http link for query and mutation and one websocket link for subscription.
When I run the code, query and mutation works fine but subscription doesn't work. The server doesn't see any subscription request but the client doesn't throw any errors.
I am not sure what I am doing is wrong. How can I see detailed information on websocket layer?
Server code:
const { ApolloServer } = require('#apollo/server');
const { makeExecutableSchema } = require('#graphql-tools/schema');
const { createServer } = require('http');
const express = require('express');
const { WebSocketServer } = require('ws');
const { ApolloServerPluginDrainHttpServer } = require('#apollo/server/plugin/drainHttpServer');
const { useServer } = require('graphql-ws/lib/use/ws');
const cors = require('cors');
const bodyParser = require('body-parser');
const { expressMiddleware } = require('#apollo/server/express4');
const { PubSub } = require('graphql-subscriptions');
const typeDefs = `#graphql
type Book {
title: String
author: String
}
input BookInput {
title: String
author: String
}
type Query {
books: [Book]
}
type Subscription {
bookCreated: Book
}
type Mutation {
postBook(input: BookInput): ID!
}
`;
const pubsub = new PubSub();
const resolvers = {
Query: {
books: () => [
{
title: 'hello',
author: 'joey',
},
],
},
Subscription: {
bookCreated: {
subscribe: () => {
console.log('receive subscribe');
pubsub.asyncIterator(['POST_CREATED']);
},
},
},
Mutation: {
postBook: async (book) => {
console.log('postBook', book)
await pubsub.publish('POST_CREATED', {
postCreated: {
title: 'Ali Baba',
author: 'Open sesame',
},
});
return '001';
},
},
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
const app = express();
const httpServer = createServer(app);
const wsServer = new WebSocketServer({
server: httpServer,
path: '/graphql',
});
const serverCleanup = useServer({ schema }, wsServer);
const server = new ApolloServer({
schema,
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
{
async serverWillStart() {
return {
async drainServer() {
await serverCleanup.dispose();
},
};
},
},
],
});
server.start().then((d) => {
console.log('started', d);
app.use('/graphql', cors(), bodyParser.json(), expressMiddleware(server));
});
httpServer.listen(4000, () => {
console.log(`Server is now running on http://localhost:4000/graphql`);
});
client code:
const { ApolloClient } = require('apollo-client');
const { InMemoryCache } = require('apollo-cache-inmemory');
const gql = require('graphql-tag');
const { createHttpLink } = require('apollo-link-http');
const ws = require('ws');
const { SubscriptionClient } = require('subscriptions-transport-ws');
const { WebSocketLink } = require('apollo-link-ws');
const fetch = require('node-fetch');
const httpLink = createHttpLink({
uri: `http://localhost:4000/graphql`,
fetch,
});
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache(),
});
const wsLink = new WebSocketLink(
new SubscriptionClient(
'ws://localhost:4000/graphql',
{
reconnect: true,
},
ws,
[]
)
);
const wsclient = new ApolloClient({
link: wsLink,
cache: new InMemoryCache(),
});
client
.query({
query: gql`
query books {
books {
author
}
}
`,
})
.then((result) => console.log(JSON.stringify(result, null, 2)));
wsclient
.subscribe({
query: gql`
subscription bookCreated {
bookCreated {
author
}
}
`,
})
.subscribe({
next: (d) => {
console.log('subscirbe', d);
},
error: (err) => console.error(err),
});
setTimeout(() => {
client
.mutate({
mutation: gql`
mutation postBook {
postBook(input: { author: "aa", title: "title" })
}
`,
})
.then((d) => console.log('mutate:', d))
.catch(console.error);
}, 1000);
Hello I am trying to upload a file using graphql in order to do this I have the following code:
index.js
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
const { graphqlUploadExpress } = require('graphql-upload');
async function startApolloServer() {
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
Mutation: {
singleUpload: async (parent, { file }) => {
const { createReadStream, filename, mimetype, encoding } = await file;
const stream = createReadStream();
const out = require('fs').createWriteStream(filename);
stream.pipe(out);
return { filename, mimetype, encoding, url: '' }
}
}
};
const server = new ApolloServer({
typeDefs:gql`
type Query {
hello: String!
}
type UploadedFileResponse {
filename: String!
mimetype: String!
encoding: String!
url: String!
}
type Mutation {
singleUpload(file: Upload!): UploadedFileResponse!
}`
, resolvers },{uploads:false});
await server.start();
const app = express();
app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
server.applyMiddleware({ app });
await new Promise(resolve => app.listen({ port: 4000 }, resolve));
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
return { server, app };
}
startApolloServer()
And in order to call the endpoint I am using the following curl:
curl localhost:4000/graphql \
-F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { filename } }", "variables": { "file": null } }' \
-F map='{ "0": ["variables.file"] }' \
-F 0=#/home/user/a.txt
But when I execute this I got the following error:
Missing multipart field ‘operations’
If I remove app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
I got another error
function deprecated(...args) {
RangeError: Maximum call stack size exceeded
But in this case I can write a empty file with the correct name.
Any idea about how can I finish this poc in order to upload a file using apollo-graphql.
Package.json
"dependencies": {
"apollo-server": "^2.25.2",
"apollo-server-express": "^2.25.2",
"graphql": "^15.5.1",
"graphql-upload": "^12.0.0"
},
"devDependencies": {
"nodemon": "^2.0.12"
},
But I tried whit this too
"resolutions": {
"**/**/fs-capacitor": "^6.2.0",
"**/graphql-upload": "^11.0.0"
}
Node version: 14.16.1 and 14.17.3
Thanks
In your typDefs, add: scalar Upload
In resolvers, add: Upload: GraphQLUpload
GraphQLUpload is imported from 'graphql-upload': import { GraphQLUpload } from "graphql-upload";
I'm creating an application where I'm using graphql and react native alongside apollo. When my server code is not using express, I'm able to successfully query from the server using
import { useQuery } from '#apollo/react-hooks';
However, I require express to be able to add a middleware and authenticate users. This throws a: Error! Network error: JSON Parse error: Unrecognized token '<'
Works with this code below (without express)
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
const books = [
{
title: 'Harry Potter and the Chamber of Secrets',
author: 'J.K. Rowling',
},
{
title: 'Jurassic Park',
author: 'Michael Crichton',
},
];
const resolvers = {
Query: {
books: () => books,
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen({ port:4000 }, () => {
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
});
-
Whereas this code below throws an error
const { ApolloServer, gql } = require('apollo-server-express')
const express = require('express');
const typeDefs = gql`
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
const books = [
{
title: 'Harry Potter and the Chamber of Secrets',
author: 'J.K. Rowling',
},
{
title: 'Jurassic Park',
author: 'Michael Crichton',
},
];
const resolvers = {
Query: {
books: () => books,
},
};
const app = express();
const server = new ApolloServer({ typeDefs, resolvers });
server.applyMiddleware({ app, path: '/graphql' });
app.listen({ port:4000 }, () => {
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
});
If this is a parse issue, how do I correctly parse the data? I've tried
app.use(bodyParser.json())
app.use(bodyParser.raw())
app.use(bodyParser.urlencoded())
app.use(bodyParser.text())
however this doesn't seem to help :/
Any ideas?
First of all, Subscriptions is working if I have next code structure
schema
type Subscription {
somethingChanged: IResult
}
type IResult {
id: String!
}
resolvers
export const resolvers = {
Query: {
},
Mutation: {
},
Subscription: {
somethingChanged: {
subscribe: () => pubSub.asyncIterator(SOMETHING_CHANGED_TOPIC)
}
},
};
The problem became be a problem when I try to make somethingChanged node as a child of another account node, like so:
So next schema and resolvers are not working
type Subscription {
account(token: String!): IAccountAction
}
type IResult {
id: String!
}
type IAccountAction {
somethingChanged: IResult
}
export const resolvers = {
Query: {
},
Mutation: {
},
Subscription: {
account: (root: any, token: string) => ({
somethingChanged: {
subscribe: () => pubSub.asyncIterator(SOMETHING_CHANGED_TOPIC)
}
})
},
};
ERROR
{
"error": {
"message": "Subscription field must return Async Iterable. Received: undefined"
}
}
I believe that is not an issue and only misunderstanding )) Please help me ))
Additional info which might help:
server.ts
import {resolvers} from './generated/resolvers';
import {typeDefs} from './generated/mergedGQLSchemas';
import http from 'http';
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
const PORT = 4001;
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers,
});
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}`);
});
I have created a node js project with graph ql (with a very basic schema) but when i am trying to start the server after registering the plugins for graphql and graphiql, i am getting the register is missing error. Below is my code
const hapi=require('hapi');
const { graphqlHapi, graphiqlHapi } = require('apollo-server-hapi');
const { makeExecutableSchema } = require('graphql-tools');
const graphqlSchema = require('./graphql/schema');
const createResolvers = require('./graphql/resolvers');
const executableSchema = makeExecutableSchema({
typeDefs: [graphqlSchema],
resolvers: createResolvers(),
});
const server=hapi.server({
port: 4000,
host:'localhost'
});
server.register({
plugin: graphqlHapi,
options: {
path: '/graphql',
graphqlOptions: () => ({
pretty: true,
schema: executableSchema,
}),
},
});
server.register({
plugin: graphiqlHapi,
options: {
path: '/graphiql',
graphiqlOptions: {
endpointURL: '/graphql',
},
},
});
const init= async()=>{
routes(server);
await server.start();
console.log(`Server is running at: ${server.info.uri}`);
}
init();
I had initially given the key name as register instead of plugin in the server.register() functions. In either case, i am getting the below error
(node:19104) DeprecationWarning: current URL string parser is
deprecated, and will be removed in a future version. To use the new
parser, pass option { useNewUrlParser: true } to MongoClient.connect.
(node:19104) UnhandledPromiseRejectionWarning: AssertionError
[ERR_ASSERTION]: I nvalid plugin options {
"plugin": {
"options": {
"path": "/graphql",
"graphqlOptions": () => ({\r\n pretty: true,\r\n schema: exe cutableSchema,\r\n })
},
"register" [1]: -- missing -- } }
Please help me out in understanding whenter code herey this happening and how it can be rectified.
Below is the dependencies in my project
apollo-server-hapi": "^2.3.1", "graphql": "^14.0.2", "graphql-tools":
"^4.0.3", "hapi": "^17.8.1",
EDIT
Code after making the suggested changes
const hapi=require('hapi');
const { graphqlHapi, graphiqlHapi } = require('apollo-server-hapi');
const { makeExecutableSchema } = require('graphql-tools');
const graphqlSchema = require('./graphql/schema');
const createResolvers = require('./graphql/resolvers');
const executableSchema = makeExecutableSchema({
typeDefs: [graphqlSchema],
resolvers: createResolvers(),
});
async function start_server() {
const server=hapi.server({
port: 4000,
host:'localhost'
});
await server.register({
plugin: graphqlHapi,
options: {
path: '/graphql',
graphqlOptions: () => ({
pretty: true,
schema: executableSchema,
}),
route: {
cors: true,
},
},
});
await server.register({
plugin: graphiqlHapi,
options: {
path: '/graphiql',
graphiqlOptions: {
endpointURL: '/graphql',
},
route: {
cors: true,
},
},
});
try {
await server.start();
console.log(`Server is running at: ${server.info.uri}`);
} catch (err) {
console.log(`Error while starting server: ${err.message}`)
}
}
start_server();
There is no need to register the plugins in the latest release of apollo-server-hapi. It contains GraphQL playground instead of graphiql.
The below changes need to be done instead of registering.
const {ApolloServer} = require('apollo-server-hapi');
const executableSchema = makeExecutableSchema({
typeDefs: [graphqlSchema],
resolvers: createResolvers(),
});
const server = new ApolloServer({
schema:executableSchema
});
async function start_server() {
const app=hapi.server({
port: 4000,
host:'localhost'
});
await server.applyMiddleware({ app });
try {
await app.start();
console.log(`Server is running at: ${app.info.uri}`);
} catch (err) {
console.log(`Error while starting server: ${err.message}`)
}
}
start_server();