Everybody likes stories. Our parents told us stories when we were young and we continue to read them through the course of our lives. They stick with us and are something that we remember clearly, as though we were reading them now. So why not start with a story.
Imagine two developers John and Jane. John is a FE (Front End) developer, while Jane is a BE (Back End) developer. They are close friends and usually do their planning together. Yet something strange happens each time.
Jane creates some REST endpoints and tells John to check them out so that he can use them on his app. Now John is not very keen on checking code each time to find out which endpoint to call so he asks Jane to deliver the documentation for the REST endpoints to him. Jane understands John and so she sends him the documentation along with Postman collection of the same API.
Some time passes and John notices that one of the endpoints is failing. John is confused because it worked yesterday and the docs are fine. John asks Jane about this issue, and guess what. Jane forgot to update the documentation for that endpoint after she changed the implementation. Jane fixes the documentation and John continues to work on his app.
John then faces another nerve-racking situation: He needed some data for his app and so he created it using API because he didn’t want to use FE mocking data. Yet each night the script Jane made drops DB and John have to do everything all over again, which is so, how can I put it, ughhh! John wants to write code not create data, but such counterproductive things continue to happen over and over again.
What is the solution you might as? Well, I could tell you that it is better communication, but then our talk would be over and so I’m not gonna suggest that. What I am gonna talk about with you is a new tool that you might already know, use or have at least heard about somewhere.
Yes, my dear reader, we are going to talk about GraphQL. Have no fear, we’re not going to go through a tutorial on how to implement it in your application. Rather, we are going to talk about how you can use GraphQL to improve those things from the story (read: implement documentation for API with no pain and provide data to FE developer without him having to create fake data through API). Yet before we start talking about it, we first need to establish some of the differences between REST, which we are using now, and GraphQL, which is the new mystery in the room.
REST has been with us for a long time and so we know its capabilities all too well:
It handles errors well. We have status code for each response that we can return to the user and in that way inform our FE developer about the state of response.It has a great caching.
Of course, there are things that REST doesn’t do well:
When you need a customized object, you either create another endpoint or create complex logic inside a currently available endpoint (which is not cool!).When we want to fetch, for example, an array of Meetups and Users this requires two requests and for each data set, you don’t get with the previous object you have to do fetch.
What about the pros and cons of GraphQL?
GraphQL is just what REST isn’t.
Handling errors could be tricky because GraphQL will always return 200 as response status and it will also return an error message and so the FE developer has to handle those messages.It does not have well implemented caching because it is one route that we call over and over.
You have one endpoint for any kind of data (you’ll see it later).It’s just one call for multiple objects that you want to fetch.It is schema oriented so it goes well with typing languages.
Is GraphQL some super Saiyan with all the bells and whistles? No, but this is a story about it and in every story the hero is always super powerful.
GraphQL is not one of those tools that give you a headache during setup and makes you cry because there are no docs about how to use it. After all, GraphQL is backed by Facebook because it ‘gave birth’ to this tool some time back in 2012 and open sourced it in 2015 and you know how generous the JS community is. Now in 2019, we have a ton of supportive tools about GraphQL and documentation about how to use it in every corner of our JS world.
For those of you who have just heard about GraphQL, this page (https://graphql.org) should be just enough to continue to follow this post.
Now GraphQL is not one of those tools that are kinda like ‘use only me and nothing else’, but it is easy to implement GraphQL with current REST API. All you do is just add another endpoint with a bit of configuration and tada GraphQL is available.
We will go with a basic implementation, nothing too fancy. You can improve it for yourself later.
We are going to install a few modules (`express-graphql` and `graphql`) and then we are going to instantiate our GraphQL. Like any other REST endpoint, we have a route that we are going to use to send queries and we have a function that spins up GraphQL.
You can see that we have a schema and that schema is defining our query. GraphQL is typed and therefore we have to define everything that we want to have in our GraphQL query IDE, which we will look at later. Another property that you can see is resolver, which defines the functions related 1:1 to the types. If we have query users then we want to have users resolver.
The schema in this basic example is just a template string, which is super easy to write and do code separation with it. There are different ways to define types with Apollo, but we won’t use them here.
The schema is the entry point where we define our query property in line with the Query type. Now you can see that it is like Typescript wherein you define the Interface and some variable and set it to that type.In the Query type, we have defined users. Users have their type, which is User. If you look there are defined properties that will return:`name, surname and age` You will notice that they also have a type, but these types are primitive such as ‘String’ for name and surname and ‘Int’ for age property.You also probably noticed that the Types have an exclamation mark (!) at their end, which means that GraphQL will never return null on that property, and on Query users property [User!], which means that it will never return null object and that the array will not be null but an empty array. The last thing we need to cover is Resolver.
The resolver is nothing more than an object that has defined functions matching Query properties, in our case user properties. In this example, we are just querying MongoDB for a list of users.
Now we can start our app. On this route, you will have your GraphQL IDE if you set the GraphQL property to true.http://localhost:3000/graphql
Now that we have our GraphQL endpoint, we are ready for a bit of experimentation. Actually, before we start with our experiment I would like to tell you something about how I came upon this, as I call it, ‘experiment’.
I was working on an MVP project with a FE developer and there it was that wild demand from that developer:
- FE developer: “I want documentation for that API upfront ... and you know I would like to have endpoints so that I can create data because I don’t want dummy data in my app … we also need to give this app to the client right away so that he can use it and see if something needs to be fixed before we start the product development.”
- BE developer (Me): “Well ...”
At that time, I had already played around with GraphQL and knew its auto-generated documentation magic. I needed something to generate data automagically and that meant that I needed to Fake data, thus Faker.js.So now that you know the story behind it, let’s jump to the experiment.
We won’t do anything super fancy here. We just need to check our resolver.
Previously we had just MongoDB query but now we will add a few more parameters to function such as fake, which is boolean and defines whether we are going to generate fake data or ask a database. We will also have a limit parameter, which is used to limit the amount of data returned from a database or to generate a specific number of dummy objects.We just created a separate generator function and pass limit and model, which we want to generate repeatedly in the array. Here we used faker to populate that model. This is what the generator looks like.
We have Array.apply() which generates null values N times and we just mapped our already defined model to it so that it populates our null values.
Voila, there is our fake data. Well it is a simple implementation but you can go nuts with it and create a module, which will serve as a general mock data generator, the possibilities are endless.
This is very basic but there are some implementations of GraphQL with faker that are just amazing, like this GraphQL-Faker. You don’t even have to create API, just run it and use it. It’s super useful for the beginning stage of a project where you want to experiment with data.Now we know how to create mocked data, but where can we really use GraphQL?Developers are using it to create middleware between their current API implementation and client app. They use it just on the client side for serving data from Redux store. There is even GraphQL implementation for ThreeJS webGL generated 3D models here as well as many more.GraphQL has a plethora of tools and one of them is Apollo, which is the next level for using GraphQL. Apollo has its client and server-side implementation where both sides could even use the same Schema (type) definitions and in that way be in sync. If familiar with Vue, the best way to try it out would be through VueCLI. VueCLI has UI that you can run with `vue ui` in the terminal, you will be guided through the creation of your Vue app.
To use Apollo in your app you just have to add a plugin (add-on) to your app over Vue UI.
After adding it you will see that a small Apollo server is generated, which means that you can start it. On the client app, you will have an example for GraphQL usage with Query fetch and Query modify data examples. Pretty cool if you ask me. GraphQL is a powerful tool but it is not a silver bullet. So don’t go around shooting each of your projects with the GraphQL tool. Use it when you really see a chance that it will improve your application or ease some part of the process. Here I’ll leave a few tools that are really good and might prove useful to you.
Before we finish, there are some usual questions regarding GraphQL that I will try to answer as best I can.
Q: Can I use GraphQL with current API? A: Of course you can, it is just a tool like any other and it goes with the microservice architecture.
Q: How can I do Authorization in GraphQL? A: I must say that all of the implementations we used were opened to public use so there were not Authentication, but in case you need it it would be just express middleware like explained in GraphQL docs here. And here is a good read if you need both authentication and authorization.
Q: What about Authentication in GraphQL? A: I must say that all of the implementations we used were open to public use and therefore there was not Authentication, but there is a good read here if you need that.
For all of you who missed our amazing meetup in Sarajevo this February, here is the presentation link Are you mocking me? - with GraphQL. Enjoy!
Now dear reader you are ready for new adventures. I hope that this read has helped you figure out if GraphQL is for you and maybe it has given you new ideas on how to improve your development process.
Thanks for sticking with me until the end, Vildan Tursic