DEV Community

Cover image for Query GraphQL API In Nextjs Data Fetching Methods - GetServerSideProps
Segun98
Segun98

Posted on

Query GraphQL API In Nextjs Data Fetching Methods - GetServerSideProps

The logical tool to use when I set out to build this website - Locallog 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  
    }  
   }`;


Enter fullscreen mode Exit fullscreen mode

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>  
     )  
    };


Enter fullscreen mode Exit fullscreen mode

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>  
 )  
}; 

Enter fullscreen mode Exit fullscreen mode

Now Let's query for a single Todo Item

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

Enter fullscreen mode Exit fullscreen mode

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  
      },  
     };  
    } 

Enter fullscreen mode Exit fullscreen mode

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(  
   … 
   )  
  };

Enter fullscreen mode Exit fullscreen mode

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  
      }  
    } `

Enter fullscreen mode Exit fullscreen mode

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>  
    )  
  };


Enter fullscreen mode Exit fullscreen mode

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

Top comments (2)

Collapse
 
vitalijalbu profile image
vitalie

Hi, can you help me pls with my code? I'd like to fetch data directly inside the component, not page. is it possible?
see here: reddit.com/r/learnjavascript/comme...

Collapse
 
successhycenth profile image
success

Good one 🙂