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

Image for post
Image for post

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!

Image for post
Image for post

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.

Image for post
Image for post
All the REST folks be like (just a joke, I love both REST and GraphQL ❤)

Getting started with GraphQL

First, we need to install the appropriate dependencies.

Image for post
Image for post

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

Image for post
Image for post

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.

Image for post
Image for post
https://github.com/apollographql/graphql-guide/blob/master/source/schemas.md

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

Image for post
Image for post

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

Image for post
Image for post
graphql query visualization

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.

Image for post
Image for post
exporting the graphql schema

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

Image for post
Image for post

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

Image for post
Image for post

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

Image for post
Image for post
registering our graphiql plugin

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.

Image for post
Image for post

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

Image for post
Image for post
graphiql interface

Woohoo, it’s working!

Image for post
Image for post
Writing our first query

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 the resolve function we left empty? Yup, that’s where we will implement data fetching from the database.

Let’s implement it!

Image for post
Image for post
Image for post
Image for post

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

Image for post
Image for post
Image for post
Image for post
Quick changes to techniques, rename to technique and type String. Basically, change techniques to technique (singular) — sorry!

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.)

Image for post
Image for post
Painting data being returned from mongoDB

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

Image for post
Image for post
graphiql API documentation

Finishing touches with swagger

Image for post
Image for post

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.

Image for post
Image for post

Now we register the plugin.

Image for post
Image for post

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

Image for post
Image for post
Image for post
Image for post

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

Image for post
Image for post
Swagger
Image for post
Image for post

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.

Note: for questions – I’m much more responsive on Twitter!

Written by

Software engineer, tech journalist, startups. Stay up to date https://thewholesome.dev, www.startupscrushing.com Twitter @ https://twitter.com/lasnindrek

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store