How we improved our code base with Apollo Client

Lluis Arévalo Salom
Ironhack Product
Published in
5 min readAug 2, 2018

Some Context

At Ironhack we have several projects to manage all the data that allow us teach our students Web Development, UX/UI Design & Data Analytics. The website and learning platforms show to the students our cohorts and the materials that learn our students. Both use a GraphQL API from where they fetch information, and we also have the admin that allow us to create new courses, students, materials…

This story is about how we started the admin and, after several months, we had to refactor all the code base to be able to scale it before add new features.

The Problem

A few months ago, we started a new project, an internal admin tool that would allow us to manage all the information we have across several platforms: website, students platform, etc. We started the project from scratch with the most trending stack of the moment: React in the Front-End and GraphQL as API.

From the very beginning we considered adding some libraries to help us manage different variables shared among the components we were creating, but we decided that the project was super simple, so it was better to avoid adding complexity to the project by using something like Redux, MobX, Apollo… it was our biggest mistake (or biggest learning, as we like to look at it).

From the very beginning, we created all the components following this pattern:

  • Parent component, rendering all the necessary components and declaring all the necessary methods to work. Its state was used to update all the child components when items were added/updated/removed.
  • Each child component receives as prop the information and methods it needs to work. At the same time, this child components, had their own child components, that had their own child components, and so on.

To have a better understanding of the problem, we’re going to show you the PageTeam Component, and some child components. The structure of the page is the following:

  • Navigation bar, with menu and filters; BarNavigation Component.
  • New user button, that shows the new user.
  • New user form, where we can add new users; TeamListInlineForm Component.
  • List of all the team members; TeamList Component.

The result is this chaotic piece of code:

Note that we left the methods empty. In the real code, each method has its own implementation. The real implementation had more of 300 lines, and as you can see, all the behaviour of the different components is here.

It looks ugly (because actually it is), but it’s not the only problem we had. To understand even better the situation, here you have part of the TeamList Component:

We use the teamMembers prop we receive to show the list of team members, however, we also pass as TeamListItem Component the methods that it’s going to be used to remove users. At the same time, this component sends this method to the deletion component, and so on.

You see now the problem: we generated a bunch of methods in the parent component, and all these events were moving among the components to be able to update the team members list in the main parent component whenever we create/update/remove a member.

As we said, the implementation was chaotic. However, while we were working on it, we didn’t notice this fact… until a few weeks ago.

When we decided to jump into the project to add some new features, we had to refactor the whole code base before started working. Here is where we decided to use Apollo.

Apollo Client

Apollo Client is a GraphQL Client that helps you build client applications that fetch data from the API in a super easy way. We decided to use it because we were looking for something easy to implement, that would allow us to refactor the code, make it more understandable, easy to maintain and scale. It allows you to add a GraphQL client without adding a huge layer of complexity.

You may be wondering how it helps our code. Well, this is the TeamPage Component that we saw before, this time refactored by adding Apollo:

This time, there’re no methods without implementation. We have implemented a huge refactor in the code, and Apollo gave us this flexibility to create a stronger and more understandable code base for our components.

And what about the other two components? Instead of fetching the team members inside the TeamPage Component, we fetch them through the Query Component that Apollo provides us. It simply executes a GraphQL query agains our API and returns the information, providing you the loading and error states, in case something goes wrong:

As you can see, the code is super easy to understand, super clean, and the Apollo methods allow us to handle both the onLoading and onError processes without doing any extra effort on our side.

The query parameter has a GET_TEAM_MEMBERS variable assigned, which is the GraphQL query that will be executed when the component is used. This variable contains this:

graphql-tag contains several utilities for parsing GraphQL queries, and it includes gql that is a JavaScript template that parses GraphQL query strings into standard GraphQL AST.

Result

The result is not just easier to understand, but also much more efficient. Thanks to Apollo cache system, it only fetches information to the server the first time you access the page.

Before using Apollo, each request that we were doing was taking about 2 seconds to fetch the information and mount all the components. After adding Apollo Client, it takes less than 1'5 seconds the first time we fetch the information. The subsequent requests are done against Apollo Cache, so the response is immediately.

Last, but definitely not least, this refactor makes our components more semantic, and allows us to separate concerns among components. Each component has its own behaviour and synchronises the actions with the Apollo cache, creating a reactivity that allow the components re-render themselves if their information has changed.

Next steps

Apollo Client helped us improving our code base and performance. Now, we have a strong code base that will allow us to work in the next features we will implement during next months:

  • Roles-based access to the different features.
  • Campus, courses, and cohorts management, as well as related features with all of them.
  • Centralise all the students information, like class performance, projects, etc.

We encourage you to check it out if you are using GraphQL and facing the same problems that we have at the beginning.

I hope you enjoyed, and thanks for reading :)

We are hiring!

Ironhack is hiring developers to grow our engineering team. If you are passionate about education, you want to work in a Full-JavaScript environment, you like to always be learning new stuff, or you simply want to know more about what we do, contact us at product@ironhack.com or apply to our job offer.

Ironhack is like a family, you can check it out int the video we did during the last company offsite in Platja d’Aro, Barcelona:

--

--