Back from a several month long hiatus, I’m coding, experimenting, and finally blogging again! This afternoon I wanna try to create a GraphQL tutorial. The idea is to introduce this new concept to people with maybe just little JavaScript experience and to be as beginner friendly as I possibly can. It’s focused on GraphQL but I’m also using a React frontend to display it. I originally intended to cover this in a video, then I thought I’d blog it because I was at a noisy Starbucks waiting for my car. I thought I could squeeze this into one post but I needed to be verbose enough to explain it for newbies. I’m finally deciding to release this as a multi-part blog series. So, with no further ado (why people tend to take there “ado” several steps further always perplexes me), I give you… LESSON.
What is GraphQL?
Let’s start by discussing what ISN’T GraphQL. It is NOT a Facebook project. It’s not a framework, it’s not a library, it’s not a replacement for RESTful services, it’s not the thing that’s going to replace you or your current work responsibilities. At it’s core, GraphQL is a specification for a Query Language to interact with an API or se of APIs, along with a runtime. That’s a bit to ingest. In simpler form, GraphQL is merely a set of rules that explain how to interact with an API (Application Program Interface) over the internet. It’s like a blueprint of best practices for using an internet API. There are many implementations of GraphQL that you can find online. Github has a GraphQL front end for their APIs with an interactive explorer web page you can use to experiment and learn. I will cover this special tool later on. I will be using an implementation written in JavaScript.
Why is GraphQL?
GraphQL began its life at Facebook as an idea of pulling data together in an efficient way for mobile devices. Way back, when Facebook for mobile was little more than a glorified webpage tucked inside a native app the engineers sought an efficient way of pulling the famous feed, interacting with the buddies list, and other uses of the Facebook API. They developed GraphQL to solve many of their pain points. GraphQL allows you to pull back data dynamically in many different varying forms with a single call to a single endpoint. It is flexible enough to evolve as your needs change without requiring deployment or re-deployment of different RESTful services or other complex infrastructure challenges. I’m gonna stop here because I’m already starting to sound like some sort of weird technical infomercial.
How do I GraphQL?
Now let’s hammer into the meat and potatoes of our lesson. (Why I chose to use a hammer with my “meat and potatoes” analogy will remain a mystery but just follow along, k?) We will begin with an ExpressJS server using nodeJS. We will introduce GraphQL with the ExpressJS server, then eventually create a React app that uses GraphQL to build a fake social network site. We’ll use and entirely original name for the site, FaceBox. If that sounds like a mouthful, relax. I’ll explain each piece. Just know for now, that there will be 2 JavaScript programs in this tutorial. One program will run directly on your computer and the other program will run in your web browser.
NodeJS is a platform that allows you to write programs with JavaScript that run outside the browser. Traditionally JavaScript was developed and intended for web browsers but some creative folks took it a step further and created this platform which runs on any computer. You can download and install NodeJS from here. Once you’ve done that you will be able to use a special command called npm to begin developing your program.The npm command is a special command line tool used to create Javascript projects and also fetch JavaScript packages from the internet. Because nobody writes a program entirely from scratch (the same way nobody boils there own molten metal to build a car or cooks the rubber for the tires) we use npm to assemble our JavaScript program from various open source packages. We won’t focus too much on nodeJS, npm, or ExpressJS. These are just a few of many packages we will use to assemble our package.
With the NodeJS part explained let’s define the other pieces. ExpressJS is a web framework that helps us build our web server, or program that serves web pages when you browse it. It’s built completely in JavaScript so you can use the same language you use in front end development to become full stack. React is a JavaScript library that allows you to build user interfaces using a special XML like syntax.
Web Server Talk
Before we start going full stack and writing code it’s important to be familiar with some basic web server terms like web addresses, and http. HTTP and HTTPS are the two popular sets of rules known as protocols which are used on the internet. In short, your web browser sends a GET request whenever you browse a web site or click a link. It’s like it’s saying to the web server, “Hey, get me the home page on twitter’s domain.” The web browser also sends either a POST or PUT request when you fill out a form, or upload an image or a video. Lastly, your browser can send a DELETE request whenever you want to delete something like removing a post or a TWEET from your timeline. There are other request types but these 4 are the more popular ones. These are the request types used to build what we call RESTful web services. I won’t go too much more in depth on how HTTP works but if you’re interested you can follow Julia Evans who does and excellent job explaining it with her comic-zines.
A web address also known as a URL is a String made up of several parts, a protocol, a host name, a port number, a context path and a query string. Let’s look at Twitter for eg. Type https://twitter.com:443/home?newtweets=true into your web browser to go to the twitter home page. The first part is the protocol, https, which stands for HTTP Secure. The protocol could be http instead, which is HTTP without the security piece. It works similarly. Most sites these days use https however there was a time where http (without the “s”) was common. The next part is the domain or host name, in this case twitter.com. This is the actual computer or machine your browser is connecting to. When you typed the example into your browser you probably noticed the port number disappeared. This is a convenience because port 443 is the default for any https web server so you don’t have to type it. The last part is the context path, /home. This directs the browser to different places on a particular domain or host. The last part is the query string. I made this ?newtweets=true query string up as it could be anything. It is just a set of name=value pairs that are introduced with a question mark. Twitter doesn’t actually use a newtweets=true query string so including it does nothing. I won’t use into query strings in this tutorial but it’s good to know what they are and where they exist in a URL.
Now with a basic definition of some core concepts we can start. Create a folder anywhere on your computer and call it faceboxGQL. Open a command terminal and change to this new directory you created. If you feel lost there are resources to help you understand how to navigate your file system on Mac or on a Windows system. Once there run the npm init command. This special command will give you a tech interview, asking a bunch of questions you might not have the answer to. Don’t sweat and just hit “Enter” on each question. It turns out that npm already knows the answer to its own questions and it merely enjoys interrogating newcomers. Once you’ve created your project you can start adding packages to it.
Run npm add nodemon express to add the first 2 important packages. The express package is a Web Server that we will use to host the GraphQL API. Next run npm add --save-dev nodemon babel-cli babel-preset-env babel-preset-stage-0 to add a few more packages. the nodemon is a tool we will use to monitor the files we will eventually add and make changes to. The babel packages are tools we will use to convert our JavaScript program from one form to another (a process known as transpiling). We use the --save-dev flag on the command line to mark these packages as development time packages. It’s a minor detail for now, but if you were to publish your program on the internet then the development packages would not be included. Inside the package.json file find the scripts section and add the following code inside it:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon ./index.js --exec babel-node -e js"
},
This block defines a start script, which holds a special command we’ll use to start the expressJS Web server. It might look like Greek or Spanglish but stay with me. We’re building towards something here.
WWW? Wait, What Web Server???
I’m so glad you asked! We don’t have a web server. We’re going to make one! That’d right, if you’re new to backend development or desiring to eventually graduate from an iHop short stack and be full stack then this is where the rubber meets the road. Create a new file in the project folder called index.js. This is where we will add the Javascript code that builds our web server. Add the following inside of index.js:
import express from 'express';
const PORT = 8090;
const app = express();
app.get('/', (req, res) => {
res.send('GraphQL is AmAzInG!');
});
app.get('/graphql', (req, res) => {
res.send('GraphQL is Not available!');
});
app.listen(PORT, () => console.log(`Running server on localhost:${PORT}/graphql`) );</pre>
That’s it! With this little bit of code you have enough to run a web server directly on your computer. The first line is an import. It defines a variable named express and imports or loads it with “stuff” from the express package that we downloaded earlier with the npm command. You don’t need to worry about the “stuff” that’s floating inside this variable anymore than you need to worry about everything that’s rotating/jiggling under the hood of your car. (That is, you only need to worry when things jiggle loosely or all smokingly.) The next line defines a port that you will browse with your web browser. Most people know what a URL or web address is but what you may not know is that you usually browse a port on a web browser. For most activities like checking Facebook or sending tweets you are browsing a default port number 443 which the browser understands so it’s not included in the URL. In this lesson you will browse your web server on a different port so we define it here. The next line creates an app object from the express package which lets you listen for different HTTP requests coming from the web browser.
The next two blocks attach some fancy ES6 functions to two different kinds of HTTP GET requests your web browser can make. The first block defines a request to the root context path, ‘/’, which is like the default. It uses an ES6 function that takes two variables, req and res for the incoming request and outgoing response respectively. The outgoing response variable holds an object that we use to call the send function inside the block. We “send” a String response which literally says, “GraphQL is AmAzInG!” The 2nd block is like the first, only it attaches to a different request context path, “/graphql” and sends a different response. A context path is the part of a web address or URL that comes after the host name. We are using the 1st block to verify that the server is up and running and this 2nd block as a placeholder where we will eventually attach our GraphQL server logic. Finally we have the last line which tells the Express app to listen on the special PORT defined earlier.
With this we are ALMOST ready to run our server but first we need to define some presets for Babel. These presets are plugins that babel uses to support different language features. Because JavaScript is a huge language with several features and because I really want to focus primarily on GraphQL, I’m going to gloss over the details of Babel presets and ask that you trust me for a moment. Create a new file called .babelrc in your project folder then copy/paste the following into it to get us moving to the next step.
{
"presets": [
"env",
"stage-0"
]
}
At this point you should be able to run your server by using the npm start command on the command line from within your project folder. After it starts you can browse the server by entering http://localhost:8090 in the address bar of your web browser. This web address has two parts, a host name localhost and the port we discussed earlier, 8090. Usually you enter web addresses without a port because the web server is running on a special port 443 which the web browser already knows to connect to. When you have a server running on a different port then it becomes necessary to include it as part of the web address.
If there are errors there are a few things you can double check. First, make sure you don’t have any other web server running on the port we defined in code. You can check this by opening your browser and trying to browse the same port without starting the server. Enter http://localhost:8090 in your browser’s address bar and see if anything appears. If you get a connection error or a site cannot be reached message then it means there isn’t any other server running on that port. Only one server can run on any given port. If you do get a page then change the const PORT = 8090 in the code to a different number run the npm start command and use this new number in your web address. If there is another error you can check the code for typos and finally try deleting the node_modules folder and running npm install command again to reinstall the project’s packages.
Finally we come to the GraphQL part. Assuming everything is working so far go back to your code editor. Also you can stop the server by typing Ctrl-C on the command line. (This special hot-key sequence will abruptly kill any program that is currently running on the command line.) We will add 3 important pieces, the GraphQL packages, a schema, and a resolver. These will be enough to build our very own GraphQL server.
GraphQL packages
Run npm install graphql express-graphql on the command line to install the GraphQL package and the Express extension for GraphQL. The graphql package contains the core GraphQL components while express-graphql contains the component objects we will use to connect our Express web server to the core. Add the following two lines to the top of the index.js file:
import graphqlHTTP from 'express-graphql';
import schema from './schema';
These lines import the express-graphql extension and a schema.js file which we have not yet defined or created. Now open the index.js file and change the 2nd block we discussed earlier to the following.
app.use('/graphql', graphqlHTTP({
schema,
rootValue: root,
graphiql: true
}));
This code calls the use function of the app object instead of the get function. In this case we are using an extension with the /graphql context path rather than connecting an ES6 function to the get method. It’s as if we’re telling express, “Hey, use this graphQL function with any request that has ‘/graphql’ as its context path.” We’re passing three values in an object to this graphqlHTTP function, a schema, a root resolver, and a boolean flag as part of a “graphiql” option. This boolean flag will enable the GraphiQL explorer interface, which is a tool that runs in the browser and lets you explore the available APIs presented by GraphQL. That will make more sense in a few, but let’s move on to the other pieces. The schema and root resolver have not yet been defined. We’ll cover that in a moment. The schema is an object that holds the definition of your API. Think of it as the ingredients section on a box of Cheerios. The root resolver is the object that actually is the API. It can be a source of data and function calls itself or work on behalf of an existing API. Let’s look at both of these objects in depth.
The Schema
Create a new file in your project folder called schema.js and copy/paste the following inside it:
import { buildSchema } from 'graphql';
const schema = buildSchema(`
type Query {
hello: String
}
`)
export default schema;
Here we import a buildSchema function from graphql at the top. We then call this function passing what looks like JSON text. This is schema definition syntax. It defines a query object that holds a single API called hello. The hello API returns a String type identified by the colon following the text hello in the curly braces. That is, the colon after the hello name separates the returned type from the name of the API. With this little bit of code we have defined the shape of our first GraphQL API. This schema definition is passed to the buildSchema function which returns a schema object. We then export the schema object as the default export from this file, which means it is the thing that is immediately visible when another JavaScript file attempts to import from this file. This schema object will be the same object that we will give to the graphqlHTTP function from the prior code snippet above.
The Resolver
The last piece we need is a query resolver. This is a special piece of code that resolves or connects a GraphQL query to some existing data or object. Open the index.js file and add this text right before the second code block we just updated with app.use.
//Query Resolver
const root = { hello: () => "Hello, It's FaceBox!"}
Here we are defining an object that has a single ES6 function named hello. This object is what we give to graphQL in the next block and it is what GraphQL will use to look up anything defined in the schema. The final index.js should look like this.
import express from 'express';
import graphqlHTTP from 'express-graphql';
import schema from './schema';
const PORT = 8090;
const app = express();
app.get('/', (req, res) => {
res.send('GraphQL is AmAzInG!');
});
//Query Resolver
const root = { hello: () => "Hello, It's FaceBox!"}
app.use('/graphql', graphqlHTTP({
schema,
rootValue: root,
graphiql: true
}));
app.listen(PORT, () => console.log(`Running server on localhost:${PORT}/graphql`) );
From the top we’ve imported the graphqlHTTP function from the express-graphql package. We’ve imported schema from our newly created schema.js file. We’ve defined an object named root with a single function named hello that returns a string, “Hello, It’s FaceBox!” We pass both the schema and the root object to the imported graphqlHTTP function and set a special graphiql flag to true. This flag activates the powerful GraphiQL explorer interface, which lets you explore all of the APIs you’ve defined in your schema. At this point you should be able to run your very first GraphQL server. Open your command terminal and run the command npm start. This should start the server and spit out a few lines of log text. You can expect to see any but not all output like, “[nodemon] to restart anytime…”, “[nodemon] watching dirs(s): *.*”, “[nodemon] watching extension: js”, “[nodemon] watching the Simpsons on Fox network, did you set your VCR to tape it?”
Open your web browser and enter the following web address, or URL: http://localhost:8090/graphql This will open the GraphiQL explorer. We’ll cover the explorer in detail in the next part of this series. For now, give yourself a pat on the back and congratulations! You’ve implemented a GraphQL endpoint and this is just the beginning!
Also, check back over the next several days as I continue to work through this post (updating any grammar or syntax mistakes) and adding new parts to the series. I’m sort of rushing this out because I’ve blabbed about it for so long. It’s premature, and not proof-read so please bear with me. Until the next part…
Peace Party People, haha! See you later!!! ✌🏽
You can find the source to this tutorial here: https://github.com/cliff76/FaceboxGQL
Also you can find a video tutorial series covering the same project.