DEV Community

Cover image for How to fetch data from a GraphQL endpoint into a NextJS 13 server component using the native fetch() API
Jerónimo Cosío
Jerónimo Cosío

Posted on

How to fetch data from a GraphQL endpoint into a NextJS 13 server component using the native fetch() API

I recently started testing out Next.js 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()to make the request.

To set up my GraphQL back-end I followed this really simple post from the 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() 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"
Enter fullscreen mode Exit fullscreen mode

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:

    query getPosts {
      posts {
        edges {
          node {
            title
            excerpt
            slug
            date
          }
        }
      }
    }
Enter fullscreen mode Exit fullscreen mode

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 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:

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());
Enter fullscreen mode Exit fullscreen mode

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.

As I'm planning on using the API data on a server component here's how the whole example would look like on an actual component:

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (3)

Collapse
 
pkellner profile image
Peter Kellner

Thanks for this. I made it a little more general and added variables. Here is the library code I created as well as an example component that uses it.

gist.github.com/pkellner/cf1154a7b...

gist.github.com/pkellner/b5f752d40...

Peter Kellner
peterkellner.net

Collapse
 
thpo profile image
Thomas Poirier • Edited

Nice. Is there a way to use the gql with the query so we can take benefit of code formatting ? And do something like this:

Image description

Collapse
 
richardnguyen99 profile image
Richard Nguyen

If you are using VSCode and have already installed the correct extension, you can put the comment #graphql as the first directive in your string interpolation.

Image description