GraphQL Beginner's Guide: Basics, Examples, and How to Use It

GraphQL is a great, intuitive tool. Here’s what you need to know about using it, including how to successfully build a Shopify GraphQL integration.

Table of Contents
Flexible work is just a click away

GraphQL is a developer-friendly query language for designing APIs. In this article we’ll take a closer look at what exactly GraphQL is and how you can use it to streamline and simplify API design.

What Is GraphQL?

GraphQL is both a query language for your API and a server-side runtime for executing queries. It greatly simplifies API design by providing a single endpoint with an expressive type system that allows you to directly define and query exactly the data you need. GraphQL isn't tied to any specific database or storage engine, giving you the flexibility to use the tools you prefer.

Benefits of GraphQL

Most developers will be familiar with REST as the de facto API design architecture used across the web that allows you to make HTTP requests to perform common data operations (e.g., GET, POST, PUT, and DELETE).

While this standard works great, it does have a few limitations, mostly due to the fact that in REST you pull the entire resource behind a URL regardless of what you actually need:

  • Overfetching: When you pull more data than necessary, usually resulting in UI code that filters the result down to what the end user needs to see (e.g., your request for a list of blog posts needs to pull all blog posts including their images, copy, and data).
  • Underfetching: When a single API request is not enough to display all the data that you need, resulting in multiple round-trip server calls (i.e., multiple resource requests).

GraphQL avoids these issues by allowing you to use a single API call to retrieve exactly the data you need to display on a page, no more no less.

GraphQL vs. REST

The biggest difference between a GraphQL and REST (Representational State Transfer) is that the former is a specific server-side application layer technology while the latter is an architectural style for creating web services.

Semantics aside, key differences between GraphQL services and RESTful services lie in how data is organized and accessed:

GraphQL REST
Specific server-side application layer developed by Facebook for executing queries. An architectural style for designing web services
Data is organized with schema and accessed through a single endpoint. Data is organized as a collection of endpoints, each with their own unique resource locator for accessibility.
Higher learning curve, faster development time Moderate learning curve, slower development time
Uses metadata for query validation Lacks cacheable machine-readable metadata
GraphQL is strongly typed REST is weakly typed

When to use GraphQL

How does GraphQL work?

Ever wonder how GraphQL is able to selectively return only the data you want—no more, no less?

In a nutshell, working with GraphQL is about defining a type system you can use to execute specific queries. Each type can have fields along with functions defining what you can do with them. Put it all together and you have a GraphQL service.

When a client sends a query to GraphQL service, a built-in query parser uses your schema to check if the incoming query is valid. If no errors are detected, it executes the functions associated with the queried fields returning a result.

How to use GraphQL: sy

To truly grasp the concepts of working with GraphQL, it’s important to dive into the documentation and try it out yourself. In the following subsections we’ll walk through the basic anatomy of a GraphQL service.

1. It starts with a schema

First, the API developer creates a schema which defines exactly the data they want to expose to client requests. They use a human-readable schema definition language (SDL) to describe a complete description of the data type and structure. It looks something like this:

--CODE language-markup line-numbers--
type Car {
  model: String #returns a String
  brand: Brand
}

type Brand {
  name: String
  cars: [Car]
}


What we have above is an example of a schema: a collection of types and the relationships between those types. In this case we have a schema that defines two object types: a Car can have an associated “brand,” and a “Brand” can have a list of “cars.”

Most schema types you define will have more than one field (this one has two) and each field returns data of the type specified. Fields can even return lists containing multiple items of a particular type using the “[ ].”

2. Use the SDL and Query type to structure your queries

GraphQL provides a special object type called “Query” that allows you to define the top-level entry point clients will use to execute queries against your server (i.e., perform read operations).

--CODE language-markup line-numbers--
type Query {
  cars: [Car]
  brands: [Brand]
}


Combined with our SDL in Step 2, we might query a list of cars in our lot with their associated brand names like so:

--CODE language-markup line-numbers--
query GetCars {
  cars {
    model
    brand {
      name
    }
  }
}


The server should respond with results that match the query’s structure with an object-based schema representation:

--CODE language-markup line-numbers--
{
  "data": {
    "cars": [
      {
        "model": "Verano",
        "brand": {
          "name": "Buick"
        }
      },
      ...
    ]
  }
}


3. Use the SDL and Mutation type to structure your write operations

The “Mutation” type can be used to define the entry points for your write operations.

--CODE language-markup line-numbers--
type Mutation {
  addCar(model: String, brand: String): Car
}


The “addCar” mutation above accepts two arguments (“model” and “brand”) and  allows us to create a new “Car” object with those fields.

Similar to queries, mutations conform to our schema’s type definitions. Let’s put “addCar” to work in the following mutation:

--CODE language-markup line-numbers--
mutation CreateBook {
  addCar(model: "Accord", brand: "Honda") {
    model
    brand {
      name
    }
  }
}


This mutation will return a corresponding object representation that matches the mutation’s structure like so:

--CODE language-markup line-numbers--
{
  "data": {
    "addCar": {
      "model": "Accord",
      "brand": {
        "name": "Honda"
      }
    }
  }
}


Congratulations, you now have the bare minimum knowledge needed to read and write to a GraphQL database. Of course as with other database technologies there is a lot more we can do with GraphQL. Refer to the documentation for a full rundown on available schema, types, fields, and functions.  

What does GraphQL’s developer ecosystem look like?

The GraphQL developer ecosystem includes a number of clients, libraries, and tools designed to help you use it with your technology stack of choice.

Popular GraphQL clients include:

  • graphql-express, which allows you to make simple HTTP requests with a Node.js server
  • Apollo Client, which is a full-featured client with useful features you can use for front-end development including the caching, batching, deduplication, and pagination of queries
  • Relay, which was developed by Facebook for using GraphQL with a React front-end
  • GQL, which is a GraphQL client for Python inspired by Relay and Apollo

Popular tools include:

  • GraphiQL IDE, which is a handy integrated development environment (IDE) that works within your browser
  • GraphQL Tools, which provides a suite of utilities for speeding up the development of GraphQL schemas

Now that you have a better idea of what tools and client libraries are available, let’s take a closer look at how you can actually use GraphQL to design APIs.

Getting started with GraphQL on Node.js

The easiest way to get started with GraphQL is to set up a simple server and install the dependencies you need to run GraphQL on that server. Because JavaScript is the most popular ecosystem for working with GraphQL we will be showing you how to get started with GraphQL on a Node.js Express server.

1. Set up your basic Node.js server

Assuming you already have Node.js installed on your machine, run the following commands to set up your server environment:

--CODE language-markup line-numbers--
npm init 
//creates your package.json file

npm i express express-graphql graphql
//installs dependencies and adds to package.json file


2. Enable automatic server reloading with nodemon

Install nodemon to eliminate the need to manually restart your server every time you change your code.

--CODE language-markup line-numbers--
npm i --save-dev nodemon
//allows us to autoreload our server whenever we save our files


Configure your Express server to work with GraphiQL

GraphiQL is a handy integrated development environment (IDE) you can use in your browser to write, test, and validate GraphQL queries. The ability to see the output next to a query can be a valuable tool when working with GraphQL.

Add the following custom script to your package.json file to run your server:

--CODE language-markup line-numbers--
 "scripts": {
    "devStart": "nodemon index.js"
  }


In your index.js file you will want to set up the necessary constants for your server with GraphQL. Copy the following code into your index.js file:

--CODE language-markup line-numbers--
const express = require('express')
const {graphqlHTTP} = require('express-graphql')
const {
    GraphQLSchema,
    GraphQLObjectType,
    GraphQLString
} = require('graphql')
const app = express()

const schema = new GraphQLSchema({
    query: new GraphQLObjectType({
        name: 'Car',
        fields: () => ({
            brand:  {
                type: GraphQLString,
                resolve: () => 'Honda'
            },
            model: {
                type: GraphQLString,
                resolve: () => 'Accord'
            }
        })
    })
})

app.use('/graphiql', graphqlHTTP({
    schema: schema,
    graphiql: true
  }))
app.listen(5000., () => console.log("Server is live"))


Now if you type localhost:5000/graphiql into your browser, you should be able to see the GraphiQL interface for querying your server:

GraphQL


Congratulations! You are now ready to play with GraphQL. Let’s start with a simple example query using the “Car” schema object we provided in the codeblock above:

GraphQL query example

With the query command, we can immediately pull the “brand” and “model” fields from the schema object defined in our index.js file. In practice, we would be hooking up GraphQL with a database and pulling JSON from there, but for the purposes of this simple example we can already play around with GraphQL using data we write directly into the index.js file.

GraphQL query example

Now that you know how to use GraphiQL to quickly validate the queries on schemas you define in your code, let’s modify our previous example (index.js file) by adding some dummy data we can use to run a custom query like so:

--CODE language-markup line-numbers--
const express = require('express')
const {graphqlHTTP} = require('express-graphql')
const {
    GraphQLSchema,
    GraphQLObjectType,
    GraphQLString,
    GraphQLList,
    GraphQLInt,
    GraphQLNonNull
} = require('graphql')
const app = express()

//Added our dummy data here, a simple list of cars
const cars = [
    {id: 1, brand: 'Honda', model: 'Accord'},
    {id: 2, brand: 'Buick', model: 'Verano'},
    {id: 3, brand: 'Mercedes-Benz', model: 'S-Class'}
]

//A complete definition of potential fields for a car with their types 
const CarType = new GraphQLObjectType({
    name: 'Car',
    description: 'represents a car with a brand and model',
    fields: () => ({
        id: { type: GraphQLNonNull(GraphQLInt)},
        brand: {type: GraphQLNonNull(GraphQLString)},
        model: {type: GraphQLNonNull(GraphQLString)}
    })
})

//A RootQueryType for our CarType to live under as an accessible object type

const RootQueryType = new GraphQLObjectType({
    name: 'Query',
    description: 'Root Query',
    fields: () => ({
        cars: {
            type: new GraphQLList(CarType),
            description: 'List of all cars',
            resolve: () => cars
        }
    })
})

//Our schema now only has to refer to the RootQueryType
const schema = new GraphQLSchema({
    query: RootQueryType
})

app.use('/graphiql', graphqlHTTP({
    schema: schema,
    graphiql: true
  }))
app.listen(5000., () => console.log("Server is live"))


To make this a bit more realistic, we have basically refactored our Car schema object from before into a more general RootQueryType which references our new list of cars. In practice this list of cars would live within a database, but for simplicity we have added it directly to our index.js file.

Now let’s use GraphQL syntax to query the brand and model of the cars in our lot:

GraphQL query list cars

As you can see, we can now query whatever fields we want from our dataset. In this case, the way we define our schema for “CarType” is what dictates what fields are available for querying.

Common GraphQL use cases

Ever wonder how convenient API development would be if instead of having to query multiple URLs for the data you need, you could send a custom query that retrieves exactly what you need from a single endpoint to rule them all?  Here are some common examples of GraphQL use cases:

When bandwidth is a premium, such as for mobile apps, smart watches, and IoT devices.

When you want to use the composite pattern to aggregate data from multiple sources into a single API endpoint.

Composite pattern

When you want to use the facade pattern to simplify an existing API

facade pattern

When you want to use the proxy pattern to add functionality to an old API

proxy pattern

Working as a GraphQL developer

In this article, we discussed what GraphQL is, how it works, and when to use it. As a query language for simplifying API design, GraphQL can be a great addition to any web developer’s toolkit.

On Upwork, the world’s human and AI-powered work marketplace, finding a GraphQL development project is as simple as signing up for an account, creating an Upwork profile, and applying directly to projects with a well-written Upwork job proposal.  

While GraphQL is language and technology agnostic, the API query language was developed with web services in mind. Naturally, JavaScript is the most mature development ecosystem for the query language. Experience with API development, JavaScript, and one of the popular GraphQL clients (e.g., Lokka, Apollo, and Relay) will look good on your Upwork profile.

Ready to put your GraphQL skills to work? Apply to GraphQL jobs on Upwork today!

Heading
asdassdsad
Do the work you love, your way

Author Spotlight

GraphQL Beginner's Guide: Basics, Examples, and How to Use It
Yoshitaka Shiotsu
Technical Copywriter & SEO Consultant

Yoshitaka Shiotsu is a project engineer turned technical copywriter and SEO consultant who regularly contributes to the Upwork Resource Center. He specializes in helping tech companies, startups, and entrepreneurs set themselves up as voices of authority within their target industries.

Latest articles

Article
How To Make a Graphic Design Portfolio That Wins Clients
Jul 1, 2026
Article
How To Write a Job Description That Attracts Top Talent
Jul 1, 2026
Article
10 Ways To Reduce Hiring Costs Without Sacrificing Quality
Jun 30, 2026

Popular articles

Article
How To Create a Proposal On Upwork That Wins Jobs (With Examples)
Jun 24, 2026
Article
Top 9 Machine Learning Skills in 2026 To Become an ML Expert
May 8, 2026
Article
The 6 Highest-Paying Machine Learning Jobs in 2026
Apr 23, 2026
Create your freelance profile today