Defining Resolvers and Schema in Node.js

Tutorial 3 of 5

Introduction

In this tutorial, we aim to learn how to define schemas and resolvers in GraphQL using Node.js. A schema in GraphQL is a blueprint for the data we can fetch, essentially an outline of our database. Resolvers in GraphQL are the functions that contain the logic to return the data for particular fields in the schema. They act like route handlers in Express.js/Node.js.

By the end of this tutorial, you will learn:
- What are schemas and resolvers in GraphQL
- How to define schemas and resolvers using Node.js
- How schemas and resolvers interact to deliver API responses

Prerequisites:
- Basic understanding of JavaScript and Node.js
- Basic understanding of GraphQL

Step-by-Step Guide

GraphQL Schemas

In GraphQL, the schema is the centerpiece of your API. It describes the shape of your data graph. It specifies what queries and mutations are available for clients to execute against your data graph.

GraphQL Resolvers

Resolvers provide the instructions for turning a GraphQL operation (a query, mutation, or subscription) into data. They either return the same type of data we specify in our schema or a promise for that data.

Defining a Schema

In GraphQL, we define the shape of our data using the Schema Definition Language (SDL). Here's how you might define a simple schema for a blog:

const { gql } = require('apollo-server-express');

const typeDefs = gql`
  type Post {
    id: ID!
    title: String!
    author: String!
    content: String!
  }

  type Query {
    posts: [Post]
    post(id: ID!): Post
  }
`;

Defining Resolvers

Resolvers in GraphQL speak directly to your database and fetch the exact data you need. Here's how you might define resolvers for the above schema:

const resolvers = {
  Query: {
    posts: () => {
      return db.posts.findAll();
    },
    post: (parent, { id }) => {
      return db.posts.findById(id);
    },
  },
};

Code Examples

Let's put it all together in a server:

const { ApolloServer, gql } = require('apollo-server-express');

// Define our schema
const typeDefs = gql`
  type Post {
    id: ID!
    title: String!
    author: String!
    content: String!
  }

  type Query {
    posts: [Post]
    post(id: ID!): Post
  }
`;

// Define our resolvers
const resolvers = {
  Query: {
    posts: () => {
      // Fetch all posts
      return db.posts.findAll();
    },
    post: (parent, { id }) => {
      // Fetch a single post by its ID
      return db.posts.findById(id);
    },
  },
};

// Initialize the Apollo Server
const server = new ApolloServer({ typeDefs, resolvers });

// Start the server
server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

Summary

In this tutorial, we covered the basics of defining schemas and resolvers in GraphQL using Node.js. We learned that the schema is the roadmap for our data, and the resolvers are the functions that get and return the actual data.

For further learning, you could explore more complex schema definitions and resolver functions, including how to handle database connections and mutations.

Practice Exercises

  1. Define a schema for a "User" with fields "id", "name", "email" and a "Query" to fetch all users and a single user by id.
  2. Create resolvers for the above schema.
  3. Create a server using the above schema and resolvers.

Solutions

  1. Defining a schema:
const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
  }

  type Query {
    users: [User]
    user(id: ID!): User
  }
`;
  1. Creating resolvers:
const resolvers = {
  Query: {
    users: () => {
      return db.users.findAll();
    },
    user: (parent, { id }) => {
      return db.users.findById(id);
    },
  },
};
  1. Creating a server:
const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});