This video is available to students only

How to Use GraphQL Mutations and Queries

In this lesson, we'll look to mimic the listings retrieval and manipulation we had in our Express RESTful API but with GraphQL instead.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

Querying and mutating listings data with GraphQL

📝 This lesson's quiz can be found - here.
🗒️ Solutions for This lesson's quiz can be found - here.

We've created a simple GraphQL Schema with which our root level query and mutation object types each have a single hello field that returns a string message when queried. We'll now look to mimic the listings retrieval and manipulation we had in our REST API with GraphQL.

Listing Object Type

The first thing we'll do is create a custom Listing object type. The Listing object type is to reference the listing type that is to be returned from our soon to be query and mutation. We'll use the GraphQLObjectType class to construct this type in the src/graphql.ts file.

The Listing type is to contain a series of fields that represent a listing.

const Listing = new GraphQLObjectType({
  name: "Listing",
  fields: {
    id: {},
    title: {},
    image: {},
    address: {},
    price: {},
    numOfGuests: {},
    numOfBeds: {},
    numOfBaths: {},
    rating: {}
  }
});

We'll need to define the types of each of the fields within Listing.

GraphQLID

GraphQL provides a unique scalar type for ID's, GraphQLID. The GraphQLID scalar type is to represent a unique identifier however it behaves and gets serialized as a String. Its main purpose is to convey that a field is to be a unique identifying field. We'll import the GraphQLID type and use it as the type of the id field.

import {
  // ...
  GraphQLID
} from "graphql";

const Listing = new GraphQLObjectType({
  name: "Listing",
  fields: {
    id: { type: GraphQLID }
    // ...
  }
});

GraphQLString

The title, image, and address fields of Listing are expected to be strings so we'll define their types with the already imported GraphQLString scalar type.

import {
  // ...
  GraphQLString
} from "graphql";

const Listing = new GraphQLObjectType({
  name: "Listing",
  fields: {
    // ...
    title: { type: GraphQLString },
    image: { type: GraphQLString },
    address: { type: GraphQLString }
    // ...
  }
});

GraphQLInt

The price, numOfGuests, numOfBeds, numOfBaths, and rating fields of Listing are expected to be integers so we'll define their types with the GraphQLInt type.

import {
  // ...
  GraphQLInt
} from "graphql";

const Listing = new GraphQLObjectType({
  name: "Listing",
  fields: {
    // ...
    numOfGuests: { type: GraphQLInt },
    numOfBeds: { type: GraphQLInt },
    numOfBaths: { type: GraphQLInt },
    rating: { type: GraphQLInt }
  }
});

For floating-point numbers (i.e. numbers with decimals), GraphQL provides the GraphQLFloat scalar type.

Our Listing object will now look like the following:

const Listing = new GraphQLObjectType({
  name: "Listing",
  fields: {
    id: { type: GraphQLID },
    title: { type: GraphQLString },
    image: { type: GraphQLString },
    address: { type: GraphQLString },
    price: { type: GraphQLInt },
    numOfGuests: { type: GraphQLInt },
    numOfBeds: { type: GraphQLInt },
    numOfBaths: { type: GraphQLInt },
    rating: { type: GraphQLFloat }
  }
});

It might be apparent that the types we specify here mimic the Listings TypeScript interface created in the src/listings.ts file.

As a reminder, TypeScript is the extension we're using to type check and reinforce our development code.

GraphQL is a typed query language for APIs so we have to define the types of the fields in our schema. There are open-source tools (e.g. GraphQL Code Generator) that help in generating TypeScript types from GraphQL schemas, but they add a layer of complexity so we won't be using them for our server code. We'll investigate how we can generate TypeScript types from a GraphQL schema when we work on the client portion of our app.

GraphQLNonNull

We'll take the type definitions for the fields in the Listing object type another step. We want all our fields in the Listing type to never be null and to always be defined. We can achieve this by using the GraphQLNonNull wrapper.

GraphQLNonNull is a type marker that enforces values are never null and will ensure an error is thrown if this ever occurs. Let's import the GraphQLNonNull wrapper in our src/graphql.ts file.

import {
  // ...
  GraphQLNonNull
} from "graphql";

We'll wrap every field type in Listing with the GraphQLNonNull wrapper which will make our Listing object type appear as follows:

server/src/graphql.ts
const Listing = new GraphQLObjectType({
  name: "Listing",
  fields: {
    id: { type: GraphQLNonNull(GraphQLID) },
    title: { type: GraphQLNonNull(GraphQLString) },
    image: { type: GraphQLNonNull(GraphQLString) },
    address: { type: GraphQLNonNull(GraphQLString) },
    price: { type: GraphQLNonNull(GraphQLInt) },
    numOfGuests: { type: GraphQLNonNull(GraphQLInt) },
    numOfBeds: { type: GraphQLNonNull(GraphQLInt) },
    numOfBaths: { type: GraphQLNonNull(GraphQLInt) },
    rating: { type: GraphQLNonNull(GraphQLFloat) }
  }
});

Root query and GraphQLList

We'll now modify our root Query object to have a field that will allow us to return an array of listing objects from the mock listings array we have in our app. We'll rename the hello field in our query object to a listings field responsible in returning a list of listings.

const query = new GraphQLObjectType({
  name: "Query",
  fields: {
    listings: {}
  }
});

The listings query field is expected to be a list of Listing items. Since we expect this field to be a list, we'll need to use the GraphQLList definition.

GraphQLList is a type wrapper that indicates a list is to be created for a particular type. Let's import the GraphQLList type.

This lesson preview is part of the The newline Guide to Building Your First GraphQL Server with Node and TypeScript course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

Unlock This Course

Get unlimited access to The newline Guide to Building Your First GraphQL Server with Node and TypeScript, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course The newline Guide to Building Your First GraphQL Server with Node and TypeScript