How to finish setting up your powerful API with Nodejs, GraphQL, MongoDB, Hapi, and Swagger (Part II)

This is part II in a series where we build a powerful GraphQL API. Please see part I first if you haven’t read it already.
I know, I left you hanging just at the exciting parts — implementing GraphQL!

What is graphQL anyway, and why is it so popular right now?
“GraphQL’s power comes from a simple idea — instead of defining the structure of responses on the server, the flexibility is given to the client. Each request specifies what fields and relationships it wants to get back, and GraphQL will construct a response tailored for this particular request. The benefit: only one round-trip is needed to fetch all the complex data that might otherwise span multiple REST endpoints, and at the same time only return the data that are actually needed and nothing more.” Source
GraphQL solves many pain points traditional REST APIs might face. Some of them are:
- Over-fetching — there is data in the response you don’t use.
- Under-fetching — you don’t have enough data with a call to an endpoint, leading you to call a second endpoint.
Check out this StackOverflow post explaining the two scenarios.
GraphQL has gotten so popular in part because people have good reason to believe it will replace REST entirely — just like REST replaced SOAP.

Getting started with GraphQL
First, we need to install the appropriate dependencies.

Graphql is the main package for graphql and apollo-server-hapi
is the glue between our Hapi server and GraphQL.
Let’s create a new folder called graphql
and inside a file called PaintingType.js

Let’s go through from top to bottom:
We require
the GraphQL library.
At line 3 we’re deconstructing objects from GraphQL.
const { GraphQLObjectType, GraphQLString } = graphql
Is the same as:
const GraphQLObjectType = graphql.GraphQLObjectType
const GraphQLString = graphql.GraphQLString
Next up, we create a new GraphQLObjectType
Almost all of the GraphQL types you define will be object types. Object types have a name, but most importantly describe their fields.
Now as you’ve likely noticed, GraphQL is a statically typed language — which means we have to declare all types for our fields. For now our field types are all the type GraphQLString
This was our query for the paintings. Now we need to hook it up to our root query which the server will serve and from where it will fetch all data.

Let’s create a file called schema.js
inside our GraphQL folder.

This is our root query which we will serve to the server.
Notice our fields section is more convoluted now — we are passing the name of the field with the type PaintingType
and args
field. Let me ask you this: how would we find a specific painting? We need some kind of argument to sort by, in this case, it would be the id
Next, we have the resolve
function which has two parameters, parent
and args
Just to illustrate, GraphQL queries look like the following

The painting
query is from PaintingType.js
— notice how we pass an argument, that’s the args
parameter in the resolve()
— and the parent would be used in more complex queries where you have more nesting going on.
Let’s export our root query and pass it to the Hapi server. Notice the type GraphQLSchema
— this is the root query/schema definition we pass to the server.

Going back to our index.js
— we require
GraphQL packages and the schema.js

Next up we need to register the hapi-graphql
plugin.

Inside the server.register({})
we pass our GraphQL configuration.

Fairly simple, eh? We installed the graphiql
plugin. Notice it’s graphiql not graphql. Graphiql is the in-browser IDE for exploring GraphQL.
Next let’s register a new plugin: the graphqlHapi which includes the schema we made earlier.

Now, if we head over to http://localhost:4000/graphiql

Woohoo, it’s working!

But why do we get a null
response? Well, two reasons.
- We probably don’t have a painting with an id of 2.
- Secondly, even if we did have a painting with
id
of 2, we’re still not fetching it from our MongoDB. Remember theresolve
function we left empty? Yup, that’s where we will implement data fetching from the database.
Let’s implement it!


Quick change for our model: let’s change technique to just a string instead of an array of strings.


Make a new request with postman with the technique field changed. Check the first article if you forgot :-)
Now we go back to our Graphiql. (By the way, check your mLab document for the appropriate id. The id has to be matching in order to get a 200 response.)

Works like a charm! An excellent feature of graphiql is that it enables API documentation out of the box.

Finishing touches with swagger

According to Swagger’s site,
Swagger offers the most powerful and easiest to use tools to take full advantage of the OpenAPI Specification.
Let’s install the dependencies.

Now we register the plugin.

And the final thing we need to do is add descriptions and tags to our routes.


All finished! Head over http://localhost:4000/documentation


Awesome, now we have a self-documenting API which we just pass to our team.
There is so much more we can do. GraphQL mutations, a frontend to consume our API, refactoring our server-side code, and so on. Let me know in the comments if it’s worth the time to write part III :)
Thanks for making it this far, hope you learned a lot and have fun with your new API! ❤
The source code;
If you want to take your GraphQL skills to the next level, check out this complete book. For JavaScript, I’d recommend reading the “You Don’t Know JS” book series.