Search code examples
javascriptnode.jsreactjsgraphqlnx.dev

Send data between GraphQL Node.js server and React in Nx


I setup two projects, Node.js and React in Nx monorepo. I would like to use GraphQL for communication. Projects I'm running with command nx serve api(Node.js) and nx serve totodile (React). Problem is that React cannot access data from /graphql endpoint.

React is running on http://localhost:4200/.
Node.js is running on http://localhost:3333/.

Node.js part

According to GraphQL instructions for Node.js I run Node.js server. I have created two endpoints /api and /graphql.

import * as express from 'express';
import { graphqlHTTP } from 'express-graphql';
import { Message } from '@totodile/api-interfaces';
import { buildSchema } from 'graphql';

const app = express();

const greeting: Message = { message: 'Welcome to api!' };

app.get('/api', (req, res) => {
  res.send(greeting);
});

app.use('/graphql', graphqlHTTP({
  schema: buildSchema(`
  type Query {
    hello : String
  }
`),
  rootValue: {
    hello: () => 'Hello world'
  },
  graphiql: true,
}));

const port = process.env.port || 3333;
const server = app.listen(port, () => {
  console.log('Listening at http://localhost:' + port + '/api');
});
server.on('error', console.error);

In a result I am able to connect to http://localhost:3333/graphql and receive response. So graphql server is working well.

// graphql response
{
  "data": {
    "hello": "Hello world"
  }
}

React part

Inside functional component I fetch with /api and /graphql. First one return valid data, but /graphql is returning 404, Cannot POST /graphql.

  useEffect(() => {
    fetch('/api') // successfully return data
      .then((r) => r.json())
      .then(setMessage);  

    fetch('/graphql', { // 404, no data
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
      body: JSON.stringify({query: "{ hello }"})
    })
      .then(r => r.json())
      .then(data => console.log('data returned:', data)); 
  }, []);

I investigate that:

http://localhost:4200/api return valid data ("message": "Welcome to api!")
http://localhost:3333/api return valid data ("message": "Welcome to api!")

http://localhost:4200/graphql 404 no data
http://localhost:3333/graphql return valid data ("hello": "Hello world")

It must be something with ports.
I don't understand how /api is able to return any data. Why on both ports?
What should I do to share data from /graphql to react?


Solution

  • To fix issue there was 2 steps to do:

    1. In React I should fetch from endpoint with port fetch('http://localhost:3333/graphql',(...))
    2. In Node.js there is need to use cors library
    import express from "express";
    import cors from 'cors';
    
    const app = express();
    
    app.use(cors());
    
    app.use('/graphql', graphqlHTTP({
     schema: schema,
     rootValue: root,
     graphiql: true,
    }));
    
    ...