Related Blogs
Frequently Apollo GraphQL API which is also known as GraphQL over REST API needs to be integrated with frontend application which is built using React or React Native technology. In the usual scenario, both GraphQL API and the React application are hosted on the same domain. But in a specific scenario, we required to develop the react application with the Apollo GraphQL API which is already hosted on some domain other than the domain of the hosted React application. Such scenario leads to challenge, as Apollo GraphQL API does not allow cross-origin request/response while application development due to security reasons.
In such scenario when we try to make request from our React application to API hosted on another domain, and API endpoint does not support cross origin request/response we get the error message as below screenshot of browser inspector window.
In order to resolve the error, if we add the headers for cross domain from client side, we will get “Method not allowed for OPTIONS” error message when we call the graphql API endpoint from react application. This happens because of our application and graphql API are running on different ports/domains.
To address this challenge, we can implement one of two solutions given below:
Solution 1: Enabling CORS module in the Apollo GraphQL API source code so that it allows cross origin request. Below is the code snippet how this can be achieved.
Code :
Installation
npm install --dev cors |
npm install –dev cors
Simple Usage (Enable All CORS Requests)
var express = require('express'); var cors = require('cors') // Added this var app = express(); app.use(cors()); // Added this |
var express = require(‘express’); var cors = require(‘cors’) // Added this var app = express(); app.use(cors()); // Added this
There are some drawback with this implementation.
- We must have access to the GraphQL API source code. If API owner is not allowing access of the code we can’t implement this solution.
- Even if API owner provide access to code and we implement this solution, it becomes security threat because now API becomes Global/Public and can be accessed by any unauthorized cross domain also.
- Implement the Apollo client for React application
import { ApolloLink } from 'apollo-link'; import { ApolloClient } from 'apollo-client'; import { InMemoryCache } from 'apollo-cache-inmemory'; import { HttpLink } from 'apollo-link-http'; const graphUrl = 'http://[appdomain]:3000/graphql'; const client = new ApolloClient({ link: new HttpLink({ uri: graphUrl }), cache: new InMemoryCache() });
import { ApolloLink } from ‘apollo-link’; import { ApolloClient } from ‘apollo-client’; import { InMemoryCache } from ‘apollo-cache-inmemory’; import { HttpLink } from ‘apollo-link-http’; const graphUrl = ‘http://[appdomain]:3000/graphql’; const client = new ApolloClient({ link: new HttpLink({ uri: graphUrl }), cache: new InMemoryCache() });
- Create a ./.env file on React application root for the API endpoint configuration dynamically API_URL=http://apidomain.com/graphql PORT=3000
- Create a config file for the API endpoint (./src/server/config/config.js) on React server
let config = { apiUrl: process.env.API_URL, apiKeyName: process.env.API_KEY_NAME, apiKeyValue: process.env.API_KEY_VALUE, port: process.env.PORT || 3000, assignKey: assignKey }
let config = { apiUrl: process.env.API_URL, apiKeyName: process.env.API_KEY_NAME, apiKeyValue: process.env.API_KEY_VALUE, port: process.env.PORT || 3000, assignKey: assignKey }
function assignKey(query){ let obj = {}; obj[config.apiKeyName] = config.apiKeyValue; return Object.assign(query, obj); }
function assignKey(query){ let obj = {}; obj[config.apiKeyName] = config.apiKeyValue; return Object.assign(query, obj); }
module.exports = config;
module.exports = config;
- Create a server file which supposed to run on node server
require('dotenv').config(); const config = require('./config/config'); const express = require('express'); const request = require('request'); const cors = require('cors'); const app = express(); const port = config.port; app.use(cors());
require(‘dotenv’).config(); const config = require(‘./config/config’); const express = require(‘express’); const request = require(‘request’); const cors = require(‘cors’); const app = express(); const port = config.port; app.use(cors());
app.use('/', function(req, res) {
app.use(‘/’, function(req, res) {
//Take the baseurl from your api and also supply whatever //route you use with that url let url = config.apiUrl + req.url; let query = config.assignKey(req.query);
//Take the baseurl from your api and also supply whatever //route you use with that url let url = config.apiUrl + req.url; let query = config.assignKey(req.query);
//Pipe is through request, this will just redirect //everything from the api to your own server at localhost. //It will also pipe your queries in the url req.pipe(request({ qs: query , uri: url })).pipe(res); });
//Pipe is through request, this will just redirect //everything from the api to your own server at localhost. //It will also pipe your queries in the url req.pipe(request({ qs: query , uri: url })).pipe(res); });
//Start the server by listening on a port app.listen(port, () => { console.log("+---------------------------------------+"); console.log(`| Listening on port:${port} |`); console.log("+---------------------------------------+"); });
//Start the server by listening on a port app.listen(port, () => { console.log(“+—————————————+”); console.log(`| Listening on port:${port} |`); console.log(“+—————————————+”); });
- Update the package.json to run the proxy server
"scripts": { ... "server-start": "node ./src/server/server.js", }
“scripts”: { … “server-start”: “node ./src/server/server.js”, }
- To start the server run below command
npm run server-start
npm run server-start
Vishal Shah
Vishal Shah has an extensive understanding of multiple application development frameworks and holds an upper hand with newer trends in order to strive and thrive in the dynamic market. He has nurtured his managerial growth in both technical and business aspects and gives his expertise through his blog posts.
Subscribe to our Newsletter
Signup for our newsletter and join 2700+ global business executives and technology experts to receive handpicked industry insights and latest news
Build your Team
Want to Hire Skilled Developers?
Comments
Leave a message...