March 16, 2019

Vica Architecture v0.5

Overview

Vica is an app that helps its users do weekly reviews.

In a nutshell, it’s a wrapper for different services like Google Calendar, Microsoft Outlook, Todoist.

It simply pulls data from those sources and presents various activities like completed Todo items and calendar events for each day.

Currently, it’s 0.5 as it doesn’t even save the Todo items and calendar events locally, all data is pulled from the service servers.

The reason for it is simple - opportunity cost.

There is a limited number of hours in the day, and most days I get only 1 hour to work on the application, but the list of things to implement is just huge.

Saving data locally, which would improve the loading speed by a large magnitude is something planned for version 1.0.

Software architecture is all about tradeoffs, and one architecture is only appropriate at the specific stage of the product. There are different requirements when you launch an app without users and when you will have a ton of traffic from 0.

These series of posts will describe the evolution of an app that goes from 0 users and just me using it to hopefully more mature application with users.

Boring tech

Boring technology is a good choice for a greenfield project. The worst that can happen when you start a new project - select some new technology which you have no prior experience. New and exciting technologies usually arise as a solution to some particular problem that team had.

Backend

Monolith

It’s counterproductive to start small projects with microservice architecture.

Currently, the application is a Django app with Celery for background tasks and scheduling.

It uses a Postgres database and Rabbitmq for background tasks orchestration (for Celery).

I’ve actually used django-cookiecutter and modified the end result a bit. This tool provides you with a template and you just set the parameters in terms of what you want to use.

But it’s a great way to kick-start the project. It sets up the basics like user models, auth, admin panel, and has sensible security out of the box.

Deployment

Currently, the app runs on the server using docker compose. No kubernetes or docker swarm. Any update is just docker pull and restarts the service.

Again, this is done as there are not so many users and a little downtime doesn’t hurt. There are plans to integrate Continuous Deployment with zero downtime, but that’s not a priority this moment.

When the app gets constant users and there could be no real downtime, then it makes sense to automate it and even introduce zero downtime deployments.

PostgreSQL and RabbitMQ are actually installed on the root server, but the web servers, celery workers are running as docker images.

Frontend

There is a mix at the moment, react for the actual application and landing page and static pages for the content.

React is build and hosted on AWS S3, same with static assets from Django app.

The landing page is served by Django. Which isn’t really efficient as I’d like to decouple it going forward. Not to break up the monolith, but just separate landing page/marketing materials and the backend, which mainly will be an API service for the app.

API

The application uses GraphQL through graphene-django as it proved to be quite easy to integrate with Django.

GraphQL is a great tool and it saves quite a lot of time in terms of development, and also ease of use so far.

I can’t comment on how it would play over the long term as I didn’t have much data or schema migration.

So far it’s been great because when you want to request a new field from the backend, you just specify it in the request, and you get it back, no need to add it on the backend and deploy a new version.

CI/CD

As I’ve mentioned, the deployment process is mostly manual at this stage. And there are no tests for backend or frontend.

Tests take time to write. In some cases, you would write more code that tests the original code than the original code itself.

Automated tests are very useful, and I will definitely add it, but it will be a gradual process, starting first with the high risk / high-value areas first.

Right now, shipping code and being confident it doesn’t break isn’t a problem. The current problem is that I don’t have users. This is what I should focus on: getting users and their feedback.

This is the reason I don’t even open source the code - the code isn’t in the greatest shape and I know it would get attention, but it would be harder for outsiders to understand these choices were made deliberately.

For example, there are methods in classes which don’t do anything as they were added as a short experiment. Or there are too many if / else statements in the code because of lack of good software patterns.

The only Continuous Integration part implemented in Vica is basically when new git commit is pushed to master branch in GitLab, it builds a docker container and pushes it to the registry so these containers can be deployed on the server.

Next steps

App architecture will be evolving all the time. The next steps are quite simple, implement webhooks, improve stability, UX and iterate based on feedback.

Since this is a side project, one of the objectives was actually to learn new technologies. So far the foundation was just the basics and I did not learn many new things.

The next step is adding webhooks, and that’s where I plan to implement the technology and patterns I want to learn.

For example, the main idea was to implement webhooks using AWS Lambda and AWS SQS, and the application will simply subscribe to the queue and retrieve the new messages.

Subscribe to my newsletter if you want to be updated when I publish new blog posts.