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.
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo 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
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
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
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 thesrc/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
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:
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
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.
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.