For the last few years, internet technologies have been shifting towards front-end JavaScript frameworks as a method of building better user experiences for web and mobile applications. This is awesome š„ I personally love the flexibility that these frameworks give us.
But has the amount of flexibility gone too farā¦
To really understand why this might be the case, letās rewind the clock and look at how apps were built before JavaScript frameworks even existed.
Prior to the development of the first few front-end frameworks (the most notable being AngularJS, Backbone, and Ember) we use to just render templates on the server and then send the full HTML page to the browser. The popular frameworks at the time included:
These frameworks revolved around the concept of the MVC a.k.a. the Model-View-Controller app development structure. Models demonstrated the āshapeā of the data, views were templates which showed how to ādisplayā the data and controllers āconnectedā the two.
I mean, there was JavaScript, but weāre talking more like jQuery sliders and some weird libraries that would make bounce effects that were completely unnecessaryā¦
Appās built on these frameworks had a couple issues but overall; everything worked pretty well. Then one day, Ryan Dahl had an awesome idea to start using JavaScript as more than just a tool to make silly animations. He developed the first version of Node.js which allowed developers to write JavaScript outside the browser and on a server instead.
Suddenly, people began appreciating the power of JavaScript and its ability to do a lot of work with only a little bit of code. This opened the mind of other developers to the possibilities of JavaScript. Not only did people begin building more powerful tools for Node.js but they also started creating interesting front-end frameworks as well. This started a snowball effect in JavaScript development over the next few years:
This began a major shift in the way apps were developed. The MVC framework, which was previously handled purely by the server, separated into two segmentsāāāa server which handled the MC (or models and controllers) and a front-end client which handled the view using one of the JavaScript frameworks above. In some of these early frameworks, they also included models and controllers in the view. Double models and controllers, some on the front-end, some on the back-endāāānow that sounds like a lot of code! šš½ā
Everyone was pretty happy. Everything worked and was relatively easy to understand once you spent a couple of hours wrapping your head around it.
Then something happenedā¦
Facebook was growing rapidly and had become the largest web-app in the world. As you can imagine, being the largest web-app comes with some challenges. One of the biggest headaches was; showing the correct number of notifications in the header bar.
As people began to do things in the Facebook app, it was expected that these little notifications would update accordingly. This was not often the case. I donāt know if you were using Facebook at the time or if you remember, but these notifications were always wrongā¦ The problem was that it was difficult for web-apps to recognise changes in one part of the app (e.g. when you read a message) and show that change in another area (e.g. reduce the unread notifications by one).
Itās not the worst thing in the worldāāāand can be solved by reloading the pageāāābut Facebook had over 1,000 passionate employees and decided it was time they would do something about this. So they rethought how the front-end frameworkās handle information and decided to create their own; React.
This new framework was good at rendering HTML but was also very barebones and did not come with much in the way of āhowā to develop apps. As such, they also launched Flux, which eventually evolved into what we call Redux (Redo-Flux). Below is the video that was on the on the Flux website back in 2014/2015. The video attempts to explain Flux and React.
The way Redux works is that it essentially stores all the dynamic information of an app in a single JavaScript object. When ever a part of the app needed to show some data, it would request the information from the server, update the single JavaScript object, and then show that data to the users. By storing all the information in one place, the app was always showing the correct information, no matter where you were looking. This thereby solved Facebookās notification problem.
So suddenly, there was an new framework for building apps; the React Redux implementation. Facebook managed to solve their problem and everyone lived happily ever after.. right?
ā Not quite.
The problem is that people (including myself) began using the single object to store all their informationāāāevery piece of data provided by the server. Sure this keeps all the information up to date, but it also has 3 main drawbacks:
We managed to turn a relatively simple task of showing data to users from a few simple templates back in 2005 with MVC frameworks into monolithic front-end apps with 10x as much code on the front-end than the back-end. For example, I recently developed a simple app and used WakaTime to measure the time I spent on my coding. Here are the results:
Are you serious?? š¤Æ I spent 8x as much time on the front-end than the back-end. Letās dive into the reason it requires so much extra code. Here is an example of the steps I need to follow to add a basic data fetch call (e.g. getting all users), to my front-end repository.
š§ Warning: the following steps are super techy so don't worry if you get lost.
fetch
call to the API.connect()
which would wrap it in a dispatch function.connect()
Ā .componentDidMount()
function.Holy molyā¦ 10 stepsā¦ Back in the good old days of Ruby on Rails, all I needed to do was give the data to my HTML template and BOOM! It would create the same result. I realised something needed to change.
Redux was great for solving the problem of keeping your front-end application in sync, however, it brought itās own problems (as mentioned before). When you think about it; how much extra functionality does Redux actually give us?
Essentially, we rewrote our entire front-endās to solve a handful of trivial problemsā¦
Anyway, Facebook also realised this and actually started to work on a new technology called GraphQL to help solve this. GraphQL is a buzzword at the moment but Iām not sure if anyone really understands why it is so cool.
GraphQL is not like Redux at all. Once again, Facebook has delivered an amazing a product but has failed to articulate why this gem of a product is so darn important; hence why I have spent the last few minutes giving you some context.
In summary, GraphQL is a car and Redux is a horse.
What? How is Redux a horse?
The reason I describe the two as a horse and a car is that; in no way would you consider a horse to be similar to a carāāāone is a living animal with four legs and the other is a machine with wheels. However, they both attempt to achieve the same end goal i.e. getting a person where they need to go. The car drives on streets and uses fuel, whereas the horse is a majestic animal which can jump over rocks. Both have different advantages and use cases, but in general; a car will get you to your end destination much faster than the horse.
So, what is GraphQL?
The official docs describe GraphQL as āGraphQL is a query language for APIsā which is very unclear. Essentially what they mean by a query language is that it essentially replaces an API with potentially hundreds of HTTP endpoints. As this technology is still young, the documentation and supporting tech is still a little difficult to understand and as such; there also a learning curve. To help, here is an example.
GraphQL will replace endpoints such as:
/users/1234567890
/cars
/example/endpoints
With custom queries which you create only when you need them. For example:
{ user(id: "1234567890") { name, email }}
Will return:
{ "user": { "name": "Luke Skywalker", "email": "[email protected]" }}
But hang onāāācustom queriesā¦ Thatās going to take ages to implement. ~ Your thoughts.
Thatās not actually true. The reason is because; by only asking for the data you need, you suddenly donāt need to make as many server requests which means that you donāt need to write as much code to handle those server requests. As such, you end up saving a tonne of time on the code you donāt have to implement.
š¤·ā But how does this replace Redux?
Another great question, thanks for asking. Simply put, it doesnāt. However, what it does do is encourage you to not store all your information in the single object that Redux gives you. This is because each query is custom designed to only get data for one part of the appāāānot the whole thing. It would be an anti-pattern (and is simply not logical) to store information, specific to a single part of the app, in an app-wide data source.
By using GraphQL, you remove your dependence on Redux and thereby remove a tonne of unnecessary code.
Something to also note is; Redux and GraphQL can co-exist in an application. This is helpful as you can slowly integrate GraphQL into your Redux application if you have already implemented it. Here are some docs on how you may go about implementing the two together.
Integrating with Redux | Apollo React Docs_By default, Apollo Client creates its own internal Redux store to manage queries and their results. If you are alreadyā¦_s3.amazonaws.com
Using Redux then becomeās a choice. Use it to solve a few trivial tasks and bring all itās overhead and problems, or replace those tasks with something else.
Okay then, so what do you use instead?
Redux was a good way of solving the problem at the time. However, since itās inception, the web development industry has exponentially advanced and with that advancement has come the introduction and improvement in the area of web sockets.
Web sockets are open connections between the server and the client so that the server can tell the client when to specifically update. And guess what? GraphQL supports web sockets straight out of the box in the form of things called subscriptions. We can therefore use these subscriptions to update the parts of our app which we would like to keep in sync.
The main difference is that; rather than having the client tell us that something needs to update (using Redux), we instead have our servers tell the client that the data must be updated. This gives us the same result. Here are a few examples of how you can implement web sockets or subscriptions directly with Mongodb or with Mongoose.
A Node.js Perspective on MongoDB 3.6: Change Streams_Before MongoDB 3.6, tailing the MongoDB oplog was the only way to listen for changes to your MongoDB database. Theā¦_thecodebarbarian.com
Mongoose v5.2.12: APIāāāModel.watch()_var schema = new Schema(..); schema.post('save', { console.log('this fired after a document was saved'); })ā¦_mongoosejs.com
GraphQL has been in development for a while, but is now at the stage where it can be comfortably used in production. I wonāt lie; the docs are rather difficult to get your head around and do require a good prior understanding on JavaScript and how servers work. However, if youāre not quite there yetāāāat least you know what to aim for. Here is a link to a popular tutorial.
GraphQL: A query language for APIs._GraphQL provides a complete description of the data in your API, gives clients the power to ask for exactly what theyā¦_graphql.org
There are also a tonne of helpful libraries which can help you can incrementally integrate it into your existing products. Donāt worry, you donāt have to do it all at once, the libraries make it easy to slowly convert your apps over time. Apollo is one company who are currently doing a great job of this.
Apollo GraphQL_Learn about the Apollo platform: Client, Engine, GraphQL servers, GraphQL support, and more._www.apollographql.com
Thatās it. I hope this article helped shed some light on some more complex concepts.
If you enjoyed this article, please give it a few claps (you can leave up to 50) or you can comment if you have any questions, Iāll do my best to answer! š
Follow me on Twitter.
Thanks!
More posts by Jack Scott.