Free Resolvers?
Yup. You read that right. You can build a GraphQL API without having to write a bunch of CRUD boiler plate. All you need to get started is Node & Neo4J.
Setup
- Node - Server-side JavaScript Runtime
- Download
- Installation
- Note: On Windows you just need to download the installer
- Neo4J - Graph Database
Getting Started
After you've setup the dependencies, we'll start setting up our Node project. Firstly we will need a folder to house our project. After we've made that, navigate into the folder and run,
$: npm init -y
This will create our package.json, marking this as a Node project. Now we're going to add this projects' dependencies,
$: npm install \
> express \
> apollo-server-express \
> neo4j-driver \
> neo4j-graphql-js
We need one more dependency to reload the app while we work.
$: npm install -D nodemon
Last thing before we get started, we should define how we're going to start our project, in the package.json file. Find the scripts section and add this line. Thanks to nodemon, our project will reload automatically any time we change any of the project files.
"start": "nodemon -e js,graphql index.js"
Next we will create a file called schema.graphql. This will house our API definition. We'll start off simple with a "type Person" and a "type Car". People will be friends with other people, as well as driving a number of Cars.
type Person {
name: ID!
friends: [Person]
drives: [Car]
}
type Car {
name: ID!
color: String
drivenBy: [Person]
}
Finally, we'll create our sole application file, index.js. In here we're going to do a number of things,
- Load the application dependencies
- Generate our complete schema
- Connect to the database
- Create our server
- Start accepting connections
// 1. Load our dependencies
const fs = require("fs");
const path = require("path");
const express = require("express");
const { ApolloServer } = require("apollo-server-express");
const { makeAugmentedSchema } = require("neo4j-graphql-js");
const neo4j = require("neo4j-driver");
// 2. Generate our complete schema
const modifiedSchema = makeAugmentedSchema({
typeDefs: fs
.readFileSync(path.join(__dirname, "./schema.graphql"))
.toString(),
});
// 3. Connect to the database
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("neo4j", "letmein")
);
// 4. Create our server
const server = new ApolloServer({
schema: modifiedSchema,
context: { driver },
});
const app = express();
server.applyMiddleware({ app });
// 5. Start accepting connections
app.listen({ port: 4000 }, () => {
console.log("Listening on port 4000");
});
To verify everything is working,
$: npm start
And visit localhost:4000/graphql in your browser. You should be greeted by the site of GraphQL Playground.
Being the observant developer you are, at this point you have probably opened the Schema tab, and noticed that... There's a lot more there than you originally wrote. Which is definitely true, but that is only the beginning of the magical things you can do with Neo4J. If you haven't already, you should scroll to the bottom of the schema. Where you'll be greeted by the root Query and Mutation objects, already filled out for you.
At this stage of the application, you can CRUD all of the People or Cars that you want. Downside is that the relationships, just aren't there yet. Now normally, in a relational database, this is where I would show you how to make join tables. But not in Neo4J. =D In Neo4J, relationships are just as important as your core data. So naturally adding relationships to your schema is just as easy as adding data. Lets go back into schema.graphql and adjust a couple lines.
type Person {
name: ID!
friends: [Person] @relation(name: "FRIEND_OF", direction: "OUT")
drives: [Car] @relation(name: "DRIVES", direction: "OUT")
}
type Car {
name: ID!
color: String
drivenBy: [Person] @relation(name: "DRIVEN_BY", direction: "OUT")
}
If you reload GraphQL Playground, and revisit the Mutation object in the schema tab. You'll see an almost overwhelming number of operations you can perform. All in the name of CRUD. However, once you look at them a bit more closely, they aren't nearly as intimidating as they might seem. Now to seed our database, run "People" -> "Cars" -> "Driving" inside GraphQL Playground from the file below...
mutation People {
Scott:CreatePerson(name:"Scott") {
name
}
Jill:CreatePerson(name:"Jill") {
name
}
Bob:CreatePerson(name:"Bob") {
name
}
First:AddPersonFriends(from:{name:"Scott"}, to:{name:"Jill"}) {
from {
name
}
to {
name
}
}
Second:AddPersonFriends(from:{name:"Jill"}, to:{name:"Bob"}) {
from {
name
}
to {
name
}
}
}
mutation Cars {
Mustang:CreateCar(name:"Mustang", color:"Black") {
name
}
Volvo:CreateCar(name:"Volvo", color:"Red") {
name
}
}
mutation Driving {
One:AddPersonDrives(from:{name:"Scott"}, to:{name:"Mustang"}) {
from {
name
}
to {
name
}
}
Two:AddPersonDrives(from:{name:"Bob"}, to:{name:"Volvo"}) {
from {
name
}
to {
name
}
}
Three:AddPersonDrives(from:{name:"Jill"}, to:{name:"Mustang"}) {
from {
name
}
to {
name
}
}
}
Conclusion
Now I will leave it to you, to play with the queries and discover the power of working with GraphQL and Neo4J. If you would like to see the code for this tutorial, you can view it anytime on Github. If this tutorial absolutely blew your mind, leave a heart and a comment. If you hate it and think it's the worst article ever published, my DM's are open. Either way, thanks for reading!
Find me on Twitter | LinkedIn
Sponsor me on Github
Like the article? Buy me a coffee!
Top comments (0)