Let’s talk about one of the biggest pains in web development: connecting your app to a database. While you might not share the same opinions, this is one of my least favorite parts of server-side development, so this tutorial will show you my tried-and-true tricks for making this go smoothly.
Firstly, when you’re just starting with databases, it can be very overwhelming as there are TONS of different options to choose from. Should you choose plain-old MySQL, MongoDB, PostgreSQL, or maybe GraphQL? If you’re thinking, “What’s the big difference?” Then don’t worry, you’re not alone; I originally thought that as well, but I can assure you that you’ll soon be on your way to database nirvana.
Using This Guide
I’m well aware that there are hundreds of other guides on the internet about this very same topic, and I can confidently say that I’ve looked at most of them. When I first started with databases and GraphQL, I was very confused. The large number of resources and various methods might leave you questioning, “Should I do it this way or that way?” Coming from somebody who’s actually tried most of the different methods, I’ll cover the easiest, simplest, and most effective ways to go about starting with a database (in my opinion).
Setting Up
As usual, I’m going to use a basic express server with EJS as my templating engine. I’m also going to arrange my project folder in the MVC format. I’m not going to show how to set up the whole project for sake of brevity, but if you’re unclear on any of these concepts, make sure to check out my articles on:
How to Add Express to a Node.js Web App
What is the MVC?
Templating With EJS and Node.js
In addition, if you just want to jump right in, you can download my boilerplate server code here on GitHub. This is the code I will be using for my server.
After we’ve gotten the basic server up and running, there is one more dependency that we need to install.
apollo-server-express
This package is responsible for setting up our GraphQL server. If you’re already familiar with GraphQL, you might realize that there is also a package called apollo-server which would work just as well. The reason I’m using apollo-server-express is so that we can run the GraphQL server alongside our Express server.
You can install this package by running:
npm i apollo-server-express -S
Later on in this series, we will probably need to install some more dependencies but this is the only other one we’ll be needing for this part.
Writing A Schema
For the next couple of following sections, I’m going to teach you some of the basic GraphQL necessities that we will need to write our GraphQL server. We won’t be able to write the server until we get through this part, so bear with me while we go over this necessary material.
One of the most important parts of GraphQL (or any query language) are parts called schemas. In short, schemas are data representations in the form of a model. For example, if we had a chat app and were storing messages in the database, we might add a message type to our schema. It might look like this:
type Message {
id: Int
text: String
from: String
}
As you can see, each message we store would have the id
, text
, and from
properties. This is like an outline that will apply to each message that we send.
To actually write our schema, we will use have to use the gql
property of the apollo-server-express
module. Check out the example below:
const { gql } = require('apollo-server-express');
const schema = gql`
type Query {
getUsers: User
}
type User {
id: Int!
username: String!
email: String!
password: String!
}
`;
In the example, we require gql
from apollo-server-express
. Then, let’s pretend we’re building the user authentication for our chat app. First, we’d define a User
model. Then, we define a Query
type. In our Query
type, we have a getUsers
method. We set this to return data of type User
. In the User
type, each user will have the following properties of id
, username
, email
, and password
. The exclamation point after the property type means that the property is non-nullable.
Writing Resolvers
The next thing we’ll need in order to get GraphQL working is to write some resolvers. Briefly, resolvers are groups of functions that act upon a GraphQL query. This means that whenever you execute a query from your schema, such as the getUsers
query we wrote above, you will need a resolver to handle the information and send back a response.
Writing resolvers is actually fairly simple. Take a look at the example below:
const resolvers = {
Query: {
getUsers: _ => 'Hello World'
}
}
Alright – this is a fairly simple object. First, we have our resolvers
object; this is where we will put all of our resolvers. Then, inside the resolvers
object, we have the Query
object. This is where we will put all our resolvers of type Query
. You can see that we defined getUsers
in the Query
type when we wrote our schema. Finally, we add our getUsers
resolver to the Query
object and set it to return the string 'Hello World'
.
It’s important to realize that the Hello World part is temporary. Since we haven’t yet set up a database model, we don’t have anything to return yet. That’s why I’m returning 'Hello World'
. Don’t worry though; we will add a dummy database model later on in the tutorial. For now though, I’m going to leave the resolvers as-is so we can start writing the server and seeing some results.
Writing The Server
Up until now, we haven’t really seen any results of our coding. We’ve mostly just been writing the code without anything happening. Well, now it’s time to write the server. Once we’ve got the server down, we’ll be able to interact with the database.
Surprisingly enough, the server is very easy to code. Take a look at the following:
const { ApolloServer } = require('apollo-server-express');
const serve = new ApolloServer({
typeDefs: schema,
resolvers: resolvers,
});
serve.applyMiddleware({ app });
In the code above, we first require ApolloServer
from the apollo-server-express
package. Then, we set up a serve
object. The typeDefs
property is where we tell the server our schema, and the resolvers
property is where we tell the server our resolvers. Then, we add the GraphQL server to our express server. The app
variable is the variable we declare when we initialize our express server.
After all this coding, the code in your index.js file should look like the following:
const port = process.env.port || 3000;
const express = require('express');
const ejs = require('ejs');
const layouts = require('express-ejs-layouts');
const app = express();
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use(layouts);
const homeController = require('./controllers/homeController.js');
app.get('/', homeController.renderIndex);
const { gql } = require('apollo-server-express');
const schema = gql`
type Query {
getUsers: User
}
type User {
id: Int!
username: String!
email: String!
password: String!
}
`;
const resolvers = {
Query: {
getUsers: _ => 'Hello World'
}
}
const { ApolloServer } = require('apollo-server-express');
const serve = new ApolloServer({
typeDefs: schema,
resolvers: resolvers,
});
serve.applyMiddleware({ app });
const server = app.listen(port, () => {
console.log(`🚀 Server listening on port ${port}`);
});
Now, to run the server, navigate to your project in your computer’s terminal/shell and run:
node index
Alright! The server is running! However, if you navigate to localhost:3000
in your web browser, you won’t see any indication that the GraphQL server is working. So, how do we know? Well, GraphQL comes with an awesome browser tool called GraphIQL. This is what we’ll use to interact with the database.
Database Interaction With GraphIQL
GraphQL wouldn’t be GraphQL without the QL part: the query language. We need to be able to retrieve, add, modify, and delete information from the database. For this, we’ll use an in-browser feature called GraphIQL.
In order to access GraphIQL, navigate to localhost:3000/graphql
with your server running. You should see something like this:
This is the online, fully interactive, GraphQL UI. This is the space where we can run and execute queries. To execute our first query, enter the code below into the box on the left and click the run button.
query findUsers {
getUsers
}
First, we define our query with the query
keyword and the name of our query (the name can be anything you want). If we only have one query, however, we don’t actually need this. The code would also work just fine if we wrote it like this:
{
getUsers
}
What this does is it executes the the getUsers
resolver. Once we run the query, it should return the following result:
{
"data": {
getUsers: 'Hello World'
}
}
It returns the string ‘Hello World’
because that is what we set it to return in our getUsers
resolver.
Adding in a Database Model
In order to keep this post short, this will be the last section. This will, however, be a series. Make sure to keep an eye out for the parts that follow, or you can subscribe for email updates.
That said, our GraphQL program and query works pretty well, but it would be pretty neat if we could retrieve actually data, not just a short string. Fortunately for us, this is well within our capabilities. First, let’s create an array of users like the one shown below.
let users = [
{
id:1,
username:'The Javascript Ninja',
email:'contact@thejavascriptninja.com',
password:'its-a-secret'
},
{
id:2,
username:'The Javascript Ninjas Best Friend',
email:'contact@thejavascriptninja.com',
password:'its-a-secret'
},
]
Above, we have two users in an array. Both users contain all the properties that we entail them to have in our schema. Next, let’s make a couple of changes to our resolvers.
From this:
const resolvers = {
Query: {
getUsers: _ => 'Hello World'
}
}
To this:
const resolvers = {
Query: {
getUsers: _ => users
}
}
Now, when we call the getUsers
resolver, it will return the data in the users array.
Wrapping Up
I’m going to end this part of the tutorial here, but this certainly isn’t the end of the series! We have only just barely scratched the surface of GraphQL and databases, so make sure to watch out for other parts of my GraphQL for Beginners series. Feel free to subscribe so you don’t miss out on any updates (there’s a form on the home page or at the top of this page if you’re interested).
As always, leave a comment or like this post if you enjoyed it or want more content like this.
Hope to see you soon!
Top comments (0)