Query GraphQL API In Nextjs Data Fetching Methods - GetServerSideProps
Published: 2020-08-28 00:12:15

The logical tool to use when I set out to build this website - [Locallog] (https://locallog.now.sh) was Nextjs, I needed SEO amongst other things that a single page app did not provide and also, Nextjs is awesome.





I used an Express server with MongoDB on the backend. It was the first time I was using a GraphQL API.  The popular tool I saw everywhere to query a GraphQL API on the front end was Apollo so I went straight to Nextjs’s Github page and looked up the Apollo example, I copied the entire code without checking the README. Querying the API worked, but I ran into issues because I didn’t query inside of Nextjs’s data fetching methods. If you are not familiar with them, check out the Docs.  



My data wasn’t fetching at request time so it did not populate the head tag and I was getting a blank screen at some point. The whole idea of using Nextjs for SEO was defeated. I raised an issue on Github and was told to use a lighter library. I consulted Google and found a library: GraphQL Request, it is a Minimal GraphQL client supporting Node and browsers for scripts or simple apps 



I will be showing you how to query and make mutations using variables. We will be building a Todo app.  

First, install the library on npm (you can also use Yarn) and import ‘request’ on your page like so:  



```
Npm i ‘graphql-request’ // in terminal  


import { request } from "graphql-request"; // in your page


We will be constructing our query like so:  



//request query
  const TODOS = ` {  
    todos{  
     id  
     name  
     completed  
     date  
    }  
   }`;


```


Here, we query for all Todo items. First we created a variable and assigned it to our request query.  

Now we would use it inside of Nextjs’ getServerSideProps, you could use getStaticProps or combine getStaticProps with getStaticPaths, read the docs on Nextjs.org.  

```
export async function getServerSideProps() {  
    //'request' from ‘graphql-request’ library 
    const res = await request(‘/api/graphiql’, TODOS);  
    const data = res.todos;  
      
    return {  
     props: {  
      data //Pass Data in props  
      },  
     };  
    }  
    //pass data into component  
    function Index({ data }) {  
     return (  
        <div> 
      ...use data here  
        {data.id}  
        </div>  
     )  
    };


```
It’s that simple, we passed in two arguments in `request(‘/api/graphql’,TODOS)`. `‘/api/graphiql’` is our request endpoint and `‘TODOS’` is the variable assigned to our query.  


```
Full code:  


import { request } from"graphql-request";
    
const TODOS = `{  
 todos{  
    id  
    name  
    completed  
    date  
  }  
 }  
`;  
  
export async function getServerSideProps(){  
 const res = await request(‘/api/graphql’,TODOS);  
 const data = res.todos;  
  
 return {  
 props: {  
   data
  },  
 };  
}  
  
function Index({ data }) {  
 return (  
      <div>  
      {data.id}  
      </div>  
 )  
}; 

```


Now Let's query for a single Todo Item



```
const TODO = `
query todo($id: String!) { // First line  
 todo(id: $id){ // Second line  
    name  
    date  
  }  
 }  
`;

```
First Line:` “$id” `here is a variable and it is a GraphQL “STRING” type (click Here to learn about all GraphQL types), the exclamation mark stands for ‘Non Null’  

Second Line: We are then assigning the variable to the argument we would pass into our request.  

Notice we only returned ‘name’ and ‘date’ from our query, excluding ’completed’. Graphql helps prevent over-fetching.  





Now let’s use it in graphql-request.  

Create a page in pages folder like so: ‘/pages/[id].js’, this allows us pass in our parameter in the request. If you are unfamiliar with this check out  Docs .  



```


  export async function getServerSideProps({params }) { //Line 1 
    const variables = { // Line 2  
     id: params.id,  
     };  
      
    const res = await request(‘/api/graphiql’, TODO, variables); // Line 3  
     const data = res.todo;  
      return {  
      props: {  
        data  
      },  
     };  
    } 

```

Line 1: we pass in ‘params’ for access to our url parameter  

Line 2: we created a ‘variables’ object to pass in the expected ‘id’ variable in our request.  

Line 3: we have a third parameter in our request where we pass in the variables.  

Now we can display a single todo item in our page.  

```

Full code:  

 const TODO = `  
  query todo($id:String!) { // First line  
   todo(id:$id) { // Second line  
        name  
        date  
   }  
   }  
  `
  export async function getServerSideProps({params }) {//Line 1  
   const variables = { // Line 2  
    id: params.id 
   };  
    
   const res = await request(‘/api/graphiql’, TODO, variables); // Line 3  
   const data = res.todo;  
   return {  
   props: {  
      data  
    },  
   };  
  }  
    
  function TodoPage({data}){  
   return(  
   … 
   )  
  };

```


We will now be making a mutation. We do not need to use a data fetching method because we are not fetching data.  




```

  const ADD_TODO = `  
   mutation addTodo( //Line One  
          $name:String!  
          $date:String  
          $completed:Boolean!)
           {  
        addPost(  
          name: $name  
          date:$date  
          completed:$completed)
           {  
          name //Line Two  
      }  
    } `

```

Line One: notice the ‘mutation’ keyword  

Line Two: we can also return data from a mutation  

Using our mutation query in the component:  



```
  function  Component () {  
    const[name, setName ] = React.useState("") //input state  

    function addTodo(e) { //submit function  
     e.preventDefault() 

    const variables = {  
          name, //from input state  
          date: new Date(),  
          completed: false  
     };
      
     try{  
     const res = await request("api/graphql", ADD_TODO, variables);   
     console.log(res.data)  
    } catch(err) {  
     console.log(err.message)  
    }  
  }   
      
    return (  
      <div>  
      …  
      </div>  
    )  
  };


```


Done! I am glad you completed this. This is my first technical post, please excuse the mistakes or better still leave a comment.