How to fetch data from a GraphQL endpoint into a NextJS 13 server component using the native fetch() API
Tags: nextjs, graphql, react, wordpress
Published: 2023-02-10 03:35:57

I recently started testing out [Next.js 13 ](https://nextjs.org/blog/next-13), and even though it's still in a beta phase I think that overall it's a really nice update and I'm already testing it out on a new project.

As it's so new there are still some examples that may be missing or are a little outdated, so I just wanted to quickly write about how to call a GraphQL backend from a server component in NextJS 13 without using any extra library and only using [fetch()](https://beta.nextjs.org/docs/api-reference/fetch)to make the request.

To set up my GraphQL back-end I followed this really simple post from the [Vercel](https://vercel.com/guides/wordpress-with-vercel) team, if you follow it correctly you will end with a GraphQL endpoint from your blog which is exactly what I needed.

Now, here's how to use the native [fetch()](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to call your recently created GraphQL end point and get -in my case- the information from the blog posts that I created on my Wordpress Blog.

The first step is to define your GraphQL endpoint url as en `env` variable, this is of course optional but it's a good practice in case it changes in the future or if you want to keep one for each of the different environments. To do this just edit or create your `.env.local` file on the root of your NextJS project and add your URL like so:

```
# .env.local
GRAPHQL_API_URL="https://youractualdomain.com/graphql"
```

Don't forget to also add this as an environment variable on your actual server.

After setting up the variable lets start looking at how to create our fetch() call and adding the query and the rest of the necessary information into it. 

For this I'll first just create my query, here's the one I'm planning on using:

``` graphql
    query getPosts {
      posts {
        edges {
          node {
            title
            excerpt
            slug
            date
          }
        }
      }
    }
```
As you can see I'm getting all the posts from my Wordpress GraphQL endpoint and receiving the title, excerpt, slug and date fields, there's more I can get if I follow the [GraphQL API for Wordpress](https://www.wpgraphql.com/) documentation, but that's all I need for the demo.

Now for actually calling the GraphQL endpoint here's how you need to structure the fetch() call:

``` javascript
const { data } = await fetch(process.env.GRAPHQL_API_URL, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: `
    query getPosts {
      posts {
        edges {
          node {
            title
            excerpt
            slug
            date
          }
        }
      }
    }
  `,
    }),
    next: { revalidate: 10 },
  }).then((res) => res.json());
```
I'm adding the GraphQL API endpoint as the first argument and then creating an object as the second. For the object on the argument I'm adding the different options for the call: 

The **method** as POST which is what GraphQL normally expects, the **header** is optional but highly recommended, and if you're doing any authentication this is normally where it goes, then on the **body** I'm adding the actual query I want to make, and finally I'm adding a **next** object and using **revalidate** which is a special option that tells the server component to re-fetch the data every 'x' amount of seconds, which in this case is 10 seconds.
If you want to learn more about how to handle the cache and other options check the [NextJS fetch documentation](https://beta.nextjs.org/docs/api-reference/fetch#optionsnextrevalidate).

As I'm planning on using the API data on a [server component](https://beta.nextjs.org/docs/rendering/server-and-client-components) here's how the whole example would look like on an actual component:

``` javascript
export default async function AllBlogPosts() {
  const { data } = await fetch(process.env.GRAPHQL_API_URL, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: `
    query getPosts {
      posts {
        edges {
          node {
            title
            excerpt
            slug
            date
          }
        }
      }
    }
  `,
    }),
    next: { revalidate: 10 },
  }).then((res) => res.json());

  let blogPosts = data?.posts?.edges;
  
  return (
    <div>
      {blogPosts?.map((post) => (
        <BlogSummary post={post.node} key={post.title} />
      ))}
    </div>
  );
}
```

And that's it, you would only need to create a `<BlogSummary /> ` component to render your posts correctly.

Let me know how you would improve this code or if you have any suggestions in the comments!