Search code examples
reactjsgraphqlapolloapollo-clientsubscription

GraphQL query with Apollo Client is returning an empty response


i'm trying to connect graphal after adding websocket and subscription to react but all reauest are returnin empty array with nod data here is my server.js

import * as dotenv from 'dotenv'
dotenv.config()
import { getUser, userProtect ,adminProtect,getAdmin} from "./Users/user.utilities.js";
import { typeDefs, resolvers } from './schema.js';
// import GraphQlUpload from 'graphql-upload'
import { ApolloServer } from '@apollo/server';
import { createServer } from 'http';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { makeExecutableSchema } from '@graphql-tools/schema';
import bodyParser from 'body-parser';
import express from 'express';
import { graphqlUploadExpress,GraphQLUpload} from "graphql-upload";
import * as path  from 'path';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import { PubSub } from 'graphql-subscriptions';
const schema = makeExecutableSchema({ typeDefs, resolvers });
const app = express();
const httpServer = createServer(app);

const wsServer = new WebSocketServer({
    server: httpServer,
    path: '/graphql'
});

const wsServerCleanup = useServer({schema}, wsServer);

const startApolloServer = async () => {
  app.use(graphqlUploadExpress())
  app.use('/images', express.static(path.join(__dirname, '/uploads/images')))

const context = async ({ req }) => {

  return {
    LogedInUser: await getUser(req.headers.token),
    LogedInAdmin: await getAdmin(req.headers.admintoken),
    userProtect,
    adminProtect
  }
}
  const server = new ApolloServer({
    schema,
    plugins: [
   
      ApolloServerPluginDrainHttpServer({ httpServer }),
      {
        async requestDidStart({ contextValue }) {
          // token is properly inferred as a string
          console.log(contextValue.token);
        },
      },
      {
       async serverWillStart() {
           return {
               async drainServer() {
                   await wsServerCleanup.dispose();
               }
           }
       }
      }
   ],
  
  })
 
  
  await server.start();
  
 
  app.use('/graphql', bodyParser.json(), expressMiddleware(server,{ context }));

}
startApolloServer()
httpServer.listen(8000, () => { console.log(`🚀 Server ready at http://localhost:4000$`) })
  ;





and here is my apollo.js in react

import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client";
import { makeVar } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
import { createUploadLink } from "apollo-upload-client";

const uploadLink = createUploadLink({ 
  uri: "http://localhost:8000/graphql" });
const authLink = setContext((_,{headers })=>{
return{
  headers:{
    ...headers,
    token:localStorage.getItem(TOKEN),
    admintoken:localStorage.getItem(ADMINTOKE)
  }
}



})
export const client = new ApolloClient({
   link:authLink.concat(uploadLink) ,
    cache: new InMemoryCache(),
  });

 

i face this problem only after adding subscriptions to server.js in nodejs

it works in studio sandbox but not in client side

enter image description here


Solution

  • here is my server after

    import * as dotenv from 'dotenv'
      dotenv.config()
      import { getUser, userProtect ,adminProtect,getAdmin} from "./Users/user.utilities.js";
      import { typeDefs, resolvers } from './schema.js';
      // import GraphQlUpload from 'graphql-upload'
      import { ApolloServer } from '@apollo/server';
      import { createServer } from 'http';
      import { expressMiddleware } from '@apollo/server/express4';
      import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
      import { makeExecutableSchema } from '@graphql-tools/schema';
      import bodyParser from 'body-parser';
      import express from 'express';
      import { graphqlUploadExpress,GraphQLUpload} from "graphql-upload";
      import * as path  from 'path';
      import { WebSocketServer } from 'ws';
      import { useServer } from 'graphql-ws/lib/use/ws';
      import { PubSub } from 'graphql-subscriptions';
      import cors from 'cors';
      const schema = makeExecutableSchema({ typeDefs, resolvers });
      const app = express();
      const httpServer = createServer(app);
      
      const wsServer = new WebSocketServer({
          server: httpServer,
          path: '/graphql'
      });
      
      const wsServerCleanup = useServer({schema}, wsServer);
      
      const startApolloServer = async () => {
        app.use(graphqlUploadExpress())
        app.use('/images', express.static(path.join(__dirname, '/uploads/images')))
      
      const context = async ({ req }) => {
      console.log(req.headers.token)
        return {
          LogedInUser: await getUser(req.headers.token),
          LogedInAdmin: await getAdmin(req.headers.admintoken),
          userProtect,
          adminProtect
        }
      }
        const server = new ApolloServer({
          schema,
          plugins: [
         
            ApolloServerPluginDrainHttpServer({ httpServer }),
           
          
            {
             async serverWillStart() {
                 return {
                     async drainServer() {
                         await wsServerCleanup.dispose();
                     }
                 }
             }
            }
         ],
        
        })
       
        
        await server.start();
        
       
        app.use('/graphql',cors(), bodyParser.json(), expressMiddleware(server,{ context }));
      
      }
      startApolloServer()
      httpServer.listen(8000, () => { console.log(`🚀 Server ready at http://localhost:4000$`) })
        ;
      
      
      
      
      

    and here is my apollo client in react

    import { makeVar } from "@apollo/client";
    import { setContext } from "@apollo/client/link/context";
    import { ApolloClient, InMemoryCache, ApolloProvider, gql } from '@apollo/client';
    import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
    import { createClient } from 'graphql-ws';
    import { split, HttpLink } from '@apollo/client';
    import { getMainDefinition } from '@apollo/client/utilities';
    import { createUploadLink } from "apollo-upload-client";
    
    
    const TOKEN = "token"
    const ADMINTOKE="admintoken"
    export const isLogedIn = makeVar(Boolean(localStorage.getItem(TOKEN)
    ));
    export const AdminisLogedIn = makeVar(Boolean(localStorage.getItem(ADMINTOKE)
    ));
    export const Dark = makeVar(false)
    
    export const AdminLogIn = (admintoken) =>{
      localStorage.setItem(ADMINTOKE , admintoken)
      AdminisLogedIn(true)
    }
    export const AdminLogOut = () =>{
      localStorage.removeItem(ADMINTOKE)
      AdminisLogedIn(false)
     
    }
    export const UserLogIn = (token) =>{
      localStorage.setItem(TOKEN , token)
      isLogedIn(true)
    }
    export const UserLogOut = () =>{
      localStorage.removeItem(TOKEN)
      isLogedIn(false)
     
    }
    const wsLink = new GraphQLWsLink(createClient({
      url: 'ws://localhost:8000/graphql',
    }));
    
    const uploadLink = createUploadLink({ 
      uri: "http://localhost:8000/graphql" });
    const authLink = setContext((_,{headers })=>{
    return{
      headers:{
        ...headers,
        token:localStorage.getItem(TOKEN),
        admintoken:localStorage.getItem(ADMINTOKE)
      }
    }
    
    
    
    })
    
    
    const splitLink = split(
      ({ query }) => {
        const definition = getMainDefinition(query);
        return (
          definition.kind === 'OperationDefinition' &&
          definition.operation === 'subscription'
        );
      },
      wsLink,
      uploadLink,
    );
    
    export const client = new ApolloClient({
      link: authLink.concat(splitLink),
      cache: new InMemoryCache()
    });