GraphQL with Apollo client with Serverless functions with Next.js

Tech Team
October 17, 2024
0 MIN READ
#security#developer-tools#tailwind#graphql#apollo

Introduction

GraphQL has revolutionized how we fetch and manage data in modern applications by providing a flexible and efficient alternative to REST APIs. When combined with Apollo Client and serverless functions in Next.js, it becomes a powerful stack for building performant, scalable applications.

In this post, we'll explore how to integrate GraphQL with Apollo Client in a Next.js application, leveraging serverless functions as the backend. We'll cover setting up Apollo Client, writing serverless GraphQL resolvers, and optimizing queries for production.

Setting Up Apollo Client in Next.js

Apollo Client is a comprehensive state management library for JavaScript that enables seamless GraphQL integration. To get started in a Next.js project, install the required dependencies:

npm install @apollo/client graphql

Next, create an Apollo Client instance and wrap your Next.js application with the ApolloProvider. This ensures that GraphQL queries and mutations are accessible throughout your app.

// lib/apolloClient.js import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client'; const httpLink = new HttpLink({ uri: '/api/graphql', // Points to our serverless function }); const client = new ApolloClient({ link: httpLink, cache: new InMemoryCache(), }); export default client;

Now, integrate Apollo Client into your Next.js _app.js:

// pages/_app.js import { ApolloProvider } from '@apollo/client'; import client from '../lib/apolloClient'; function MyApp({ Component, pageProps }) { return ( <ApolloProvider client={client}> <Component {...pageProps} /> </ApolloProvider> ); } export default MyApp;

Creating Serverless GraphQL Resolvers

Next.js API routes can be used to create serverless GraphQL endpoints. We'll use graphql and apollo-server-micro to define our schema and resolvers.

First, install the necessary packages:

npm install apollo-server-micro graphql

Next, create a GraphQL API route in pages/api/graphql.js:

// pages/api/graphql.js import { ApolloServer, gql } from 'apollo-server-micro'; const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: () => 'Hello from GraphQL!', }, }; const apolloServer = new ApolloServer({ typeDefs, resolvers }); export const config = { api: { bodyParser: false, }, }; export default apolloServer.createHandler({ path: '/api/graphql' });

This sets up a basic GraphQL server with a single hello query. You can test it by sending a query to /api/graphql using a tool like Apollo Studio or Postman.

Fetching Data with Apollo Client

With the serverless GraphQL endpoint ready, let's fetch data in a Next.js component. We'll use the useQuery hook from Apollo Client.

Here’s an example component that queries the hello field:

// components/HelloQuery.js import { useQuery, gql } from '@apollo/client'; const GET_HELLO = gql` query GetHello { hello } `; export default function HelloQuery() { const { loading, error, data } = useQuery(GET_HELLO); if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error.message}</p>; return <h1>{data.hello}</h1>; }

This demonstrates how Apollo Client simplifies data fetching by handling loading and error states automatically.

Optimizing for Production

For production applications, consider the following optimizations:

  1. Persisted Queries: Reduce payload size by sending query hashes instead of full queries.
  2. Caching Strategies: Customize InMemoryCache to improve performance.
  3. Serverless Deployment: Ensure your Next.js API routes are optimized for serverless execution (e.g., Vercel or AWS Lambda).

Here’s an example of a more advanced resolver with data fetching:

// pages/api/graphql.js import { ApolloServer, gql } from 'apollo-server-micro'; import fetch from 'node-fetch'; const typeDefs = gql` type Post { id: ID! title: String! body: String! } type Query { posts: [Post!]! } `; const resolvers = { Query: { posts: async () => { const res = await fetch('https://jsonplaceholder.typicode.com/posts'); return res.json(); }, }, }; const apolloServer = new ApolloServer({ typeDefs, resolvers }); export const config = { api: { bodyParser: false, }, }; export default apolloServer.createHandler({ path: '/api/graphql' });

Conclusion

Combining GraphQL, Apollo Client, and serverless functions in Next.js provides a scalable and efficient way to manage data in modern applications. By leveraging Next.js API routes, you can create a performant backend without managing a dedicated server.

This setup is ideal for JAMstack applications, microservices, or any project requiring flexible data fetching. Experiment with advanced features like subscriptions, authentication, and caching to further enhance your GraphQL implementation.

Happy coding! 🚀

Share this article