@adlrocha - Personal project: Financial dashboard
A way of learning GraphQL and ReactJS
|Alfonso de la Rocha||Sep 8, 2019|
I am horrible with languages. This is also the case for programming languages, so whenever I want to learn a new programming language or technology I have to use a extremely practical way of learning. In my case, I can’t stand reading docs and tutorials that I will forget 30 seconds after reading them. I have a lack of short-term memory, this is why, the best way I know of learning something new is challenging myself with a “motivating” project to force me to think and read through the aforementioned boring docs and tutorial in order to make things work and achieve a clear goal.
Instead of starting the obvious and typical projects every tutorial teaches, and everyone follows when they are learning (the to-do list, a hello-world, an instagram for dogs, etc.), I need projects for which I don’t have a solution, so I have to find my way through the target technology. To choose a potential project, what I do is analyze needs I may have and that may be fulfilled with the technology I want to learn, and I force myself to implement it using this newly acquired skill/technology.
And all of this leads me to the topic of today’s publication, the side-hustle I’ve been working on the past few weekends in order to learn GraphQL and frontend development. I have been wanting to learn GraphQL and at least some (considering my lack of artistic taste) frontend development for a while, so what was the project I was going to build to force me to learn? A financial dashboard. And the need I was going to fulfill? A way of monitoring all my assets and expenses from a single system so that with a quick look I could decide the number of books, beers and trips I can afford with what’s left of my paycheck and my investments.
GraphQL in the back
My only requirement in the backend was to use GraphQL for the API interactions. What’s GraphQL? It is a query language to implement more efficient data interactions compared with REST APIs. GraphQL can be implemented using many backend technologies. I was tempted to use Golang for the backend, but as I was going to use React for the frontend, I decided to stick with NodeJS and Express. For the database I decided to use MongoDB. There is no specific reason for this apart from the fact that I prefer NoSQL to SQL databases, and that I am used to work with it in a daily basis.
The ExpressJS implementation part was pretty easy. In the end I just had to expose two routes: one for the frontend and the other one for GraphQL. This simplifies significantly the number of routes that would have been required for a standard REST API.
Data in GraphQL is modeled using schemas, and the interaction with the data is performed using queries and mutations (i.e. “GETting” data and “POSTing” data ). GraphQL has an advantage over REST APIs though, when you request an asset to the server using a query, you don’t have to ask for all, or the same attributes of the asset every time, depending on the purpose of the call, without additional implementations you can chose the specific data you need (without unnecessarily overloading the request).
For the application, I decided to implement two assets: one to describe a specific financial asset, its category, and its history; and a history type belonging to a specific asset where I tracked the value/amount of the asset in a specific point of time.
Over this data, I would make GraphQL queries and mutations to request data, create a new asset, update an asset, gets its history, etc. Implementing this with GraphQL is extremely simple, elegant and convenient. Let me share an example of my query functions:
And in case you are wondering, how would a GraphQL request and response look like? With this simple request we can create a new asset and request only the data we are interested in.
The architecture of the front
Now I had the backend server up and running, time to get my hands dirty with the frontend development. After briefly reading about different frontend technologies and frameworks, I decided to start with React (to be completely fair I already knew a bit of React, so that way I could have a head start for the project).
For the interaction with the backend, I could have chosen may options: writing raw GraphQL requests (in the end you can send a POST request with the GraphQL request in the body to the /graphql endpoint); using express’ GraphQL client; or (the option I chose), using a GraphQL framework to easily do fancy stuff. Consequently, I chose Apollo for the frontend interaction with GraphQL.
I usually hate to use frameworks when is not strictly needed, because I hate not knowing/understanding what is going on underneath. However, Apollo simplified for me really cool things such as periodic polling of data to the backend (in order to have an “almost” real time dashboard), cache of data (so that even if several components required the same data redundant calls are not made to the backend), and many other things I didn’t have the chance to play with yet.
For the frontend, I decided to implement four simple views: one with an overview of my assets, another one where I could easily create new assets, another with the details of an asset, and one to update and delete assets.
Making it pretty with charts
I implemented the frontend layout, I managed to successfully request the data, now I just needed to improve the UX so that the system could be used for what it was meant for: tracking my financial health in a single look. And what better way to understand a bunch of data in a single look than with charts and graphs? I chose to use ChartJS to include graphs into my components. And this is the result (let me share a few screenshots so you can have a glimpse of the looks and functionality of my system)
My overview of assets, with their current amount and category.
Overview of charts.
Details for an asset.
The project has serve its basic purpose, I managed to learn GraphQL and a bit of React. Nonetheless, there are a few improvements I am looking to implement in my spare time such as:
The first improvement is obvious. I want to make the system prettier. Right now it has a basic design, and the UX could be improved. I may ask a friend to help me with this (again, making things pretty is not one of my strengths).
Multiuser support and authentication. Right now, is just me using it in my local machine (I haven’t even deployed it yet), however, some people already asked me to have access to the system (at least to test it), and in order to do this I need to secure the GraphQL and support multiple users (I don’t want people messing up my finances).
A middle term feature I want to include is the automatic update of data of assets. Right now, the history of assets must be manually updated. I want to try and connect the system to my bank and investments accounts to enable the automatic update of data (so that no I can actually get real time data about my assets).
Finally, and this is a long term goal, I want to implement expenses and revenue forecasts in the system. With enough information about asset histories I feel I would be able to make slightly accurate forecasts of my assets to ease my financial planning.
If there is anything else you would like to see in a project like this do not hesitate to share your thoughts.
Open sourcing it or offering it as a service?
Obviously what I currently have is a quite limited MVP with a really small number of functionalities, but enough to solve my needs (and learn some new skills in the process). Up till know it has been a “only for my eyes” project, but it is time for me to decide (with your help) what to do with it. If enough people finds it useful to have a service such as this, I can deploy it and offer it free (at least for now) as a service.
If no one would use the system, and you think the only interesting thing about the project is inspecting the code to see how things work, then I can publish the project’s repo for everyone to check it, use it and, maybe, contribute to it.
Again, I would really appreciate your feedback about the matter. Thank you for reading.