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

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

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.

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.

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.

1
const { GraphQLObjectType, GraphQLString } = graphql

Is the same as:

1
const GraphQLObjectType = graphql.GraphQLObjectType
1
const GraphQLString = graphql.GraphQLString

Check out this article about deconstruction.

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.

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

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

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.

exporting the graphql schema

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.

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.

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

graphiql interface

Woohoo, it’s works!

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

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

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.

graphiql api documentation


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 final thing we need to do is add descriptions and tags to our routes.

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

Swagger

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! ❤

Note: I love to chat on Twitter!

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×