Handling More Complex Data Queries in Apollo Server 4

Introduction and Context Setting

Welcome to the lesson on "Handling More Complex Data Queries," as part of the "Comprehensive Intro to GraphQL in TypeScript" course. In this lesson, we'll expand on what we learned about mutations in the previous lesson. We'll focus on setting up nested queries in GraphQL to handle more intricate relationships between data, specifically authors and books.

Defining the Schema with Nested Queries

To handle nested queries, we need a schema that represents our data types and their relationships.

  1. Define Data Types

    We'll create Author and Book types with fields that reference each other:

    import { ApolloServer } from '@apollo/server';
    
    const typeDefs = `#graphql
      type Author {
        id: ID!
        name: String!
        books: [Book]
      }
    
      type Book {
        id: ID!
        title: String!
        author: Author
      }
    
      type Query {
        books: [Book]
        authors: [Author]
      }
    `;
    • Author has fields id, name, and books, which is an array of Book.
    • Book has fields id, title, and an author, which is of type Author.
  2. Sample Data

    Define some sample data to work with:

    const authors = [
      { id: '1', name: 'J.R.R. Tolkien' },
      { id: '2', name: 'J.K. Rowling' }
    ];
    
    const books = [
      { id: '1', title: 'The Hobbit', author: '1' },
      { id: '2', title: 'Harry Potter', author: '2' }
    ];

    This data will be used to simulate a small library.

Implementing Resolvers For Nested Queries

Resolvers are responsible for fetching the data defined in your schema.

  1. Define Resolvers

    Here's how you can write resolvers to handle nested queries:

    const resolvers = {
      Query: {
        books: () => books,
        authors: () => authors
      },
      Book: {
        author: (book: any) => authors.find(author => author.id === book.author)
      },
      Author: {
        books: (author: any) => books.filter(book => book.author === author.id)
      }
    };
    • The Query resolvers return the sample data for books and authors.
    • The Book resolver finds the author of a given book.
    • The Author resolver filters books written by a given author.
  2. Initialize Apollo Server

    Combine the schema and resolvers to set up the server:

    import { startStandaloneServer } from '@apollo/server/standalone';
    
    const server = new ApolloServer({ typeDefs, resolvers });
    
    const { url } = await startStandaloneServer(server, { listen: { port: 4000 } });
    console.log(`🚀 Server ready at ${url}`);

    When you run your server.ts file, it should print:

    🚀 Server ready at http://localhost:4000/
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal