Search code examples
javascriptreactjsgraphqlapollogithub-graphql

Github GraphQL API link not fetching data through React Web App, Error Found


I want to create a react web app that outputs data from github with the GitHub graphql API. So I used a method that I used in creating a weather web app which still uses graphql and react but my app throws an error because the data cannot be feteched from GitHub. The error returned in the console indicates it is a post 401 error associated with the link I add as my URI which is https://api.github.com/graphql . I have the web app as it is right now on my repository. Below is the error shown on the browser console and the three files of my code. Thankyou in advance.

enter image description here

The three files with the code:
• App.js

import './App.css';
import Home from "./Pages/Home.jsx";
import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client";

function App() {

  const client = new ApolloClient({
    cache: new InMemoryCache(),
    uri: "https://api.github.com/graphql",
  });

  return (
    <ApolloProvider client={client}>
      <Home />
    </ApolloProvider>
  );
}

export default App;

• Home.jsx

import { useLazyQuery } from "@apollo/client";
import { GET_REPO_OWNER_NAME } from "../graphql/Queries.js";


const Home = () => {

  const [getRepoName, {loading, data, error}] = useLazyQuery(GET_REPO_OWNER_NAME);

  if(error) return <h1>Error found</h1>
  if(data){
    console.log(data);
  }

  return (
    <div className="home">
      <h1>Github Issue Tracker</h1>
      <input type="text" placeholder="City name..." />
      <button onClick={ () => getRepoName() }>Search</button>
    </div>
  );
};

export default Home;

• Queries.js

import { gql } from "@apollo/client";

export const GET_REPO_OWNER_NAME = gql `
  query { 
    viewer { 
      login
    }
  }
`;

Solution

  • You are missing the auth token in your code, take a look here on how to create one.

    In the official GitHub docs about graphql is specified you need an OAuth token and there are some resource limitations

    To communicate with the GraphQL server, you'll need an OAuth token with the right scopes.

    Follow the steps in "Creating a personal access token" to create a token. The scopes you require depends on the type of data you're trying to request. For example, select the User scopes to request user data. If you need access to repository information, select the appropriate Repository scopes.

    Update your App.js file with this:

    import './App.css';
    import Home from "./Pages/Home.jsx";
    import { ApolloClient, InMemoryCache, ApolloProvider, createHttpLink } from "@apollo/client";
    import { setContext } from '@apollo/client/link/context';
    
    function App() {
    
        // Set your localstorage variable called token
        localStorage.setItem('token', 'my-fancy-token-string');
    
        // Create the http link
        const httpLink = createHttpLink({
            uri: 'https://api.github.com/graphql',
        });
    
        // Generate and set the header with the auth details
        const authLink = setContext((_, { headers }) => {
            // get the authentication token from local storage if it exists
            const token = localStorage.getItem('token');
            // return the headers to the context so httpLink can read them
            return {
                headers: {
                    ...headers,
                    authorization: token ? `Bearer ${token}` : "",
                }
            }
        });
    
        // Generate your client with the authLink and httpLink
        const client = new ApolloClient({
            cache: new InMemoryCache(),
            link: authLink.concat(httpLink)
        });
    
        return ( <
            ApolloProvider client = { client } >
            <
            Home / >
            <
            /ApolloProvider>
        );
    }
    
    export default App;
    

    For more details you can take a look to the official documentation of apollo

    NOTE: Remember that the OAuth token is like your account password, so you MUST keep it secret and don't share it, pay attention to not push it on github when you update your code. To avoid any problem don't keep your token in the code like localStorage.setItem('token', 'my-fancy-token-string'); but put it as environment variable instead.

    You can do it on linux like export MYTOKEN=my-fancy-token-string. In your code you can read it using const token = process.env.MYTOKEN;

    Code to read from env variables:

    import './App.css';
    import Home from "./Pages/Home.jsx";
    import { ApolloClient, InMemoryCache, ApolloProvider, createHttpLink } from "@apollo/client";
    import { setContext } from '@apollo/client/link/context';
    
    function App() {
        // Create the http link
        const httpLink = createHttpLink({
            uri: 'https://api.github.com/graphql',
        });
    
        // Generate and set the header with the auth details
        const authLink = setContext((_, { headers }) => {
            // get the authentication token from env variables if it exists
            const token = process.env.MYTOKEN;
    
            // return the headers to the context so httpLink can read them
            return {
                headers: {
                    ...headers,
                    authorization: token ? `Bearer ${token}` : "",
                }
            }
        });
    
        // Generate your client with the authLink and httpLink
        const client = new ApolloClient({
            cache: new InMemoryCache(),
            link: authLink.concat(httpLink)
        });
    
        return ( <
            ApolloProvider client = { client } >
            <
            Home / >
            <
            /ApolloProvider>
        );
    }
    
    export default App;