And that's it ! All the rest is containerised !
This section covers the development of different services. For each service, we discuss:
- The reasons behind the technology choices
- Their architecture
- Potential challenges encountered
The frontend was developed using the Angular framework with TypeScript. This choice was made because Arno was already familiar with this framework, and Nathan was interested in discovering it through this project.
Here is the simplified architecture of the frontend application:
.
├── angular.json
├── dist
│ └── [Compiled JS files sent to the browser]
├── dockerfile
├── node_modules
│ └── [Everything]
│ └── [A lot]
│ └── [Of]
│ └── [Packages]
│ └── […]
├── src
│ ├── app
│ │ ├── app.component.html
│ │ ├── app.component.scss
│ │ ├── app.component.ts
│ │ ├── app.config.ts
│ │ ├── app.routes.ts
│ │ ├── features
│ │ │ └── [UI components used in the main component]
│ │ └── shared
│ │ │ └── [Shared UI components]
│ ├── assets
│ │ └── [Images and SVG files used for display]
│ ├── environments
│ │ └── [Dev and prod environment variables]
│ ├── favicon.ico
│ ├── index.html
│ ├── main.ts
│ └── styles.scss
└── [Some TypeScript configuration files]
One of the biggest challenges we faced in choosing Angular over a simple HTML/CSS/JS app was the increased complexity and learning curve. We took some time to set up the project and Arno had to teach Nathan on how the frameworks works.
The backend was written in Python using the Flask package to set up the API. Additional packages such as pika and redis were installed for communication with RabbitMQ services and the Redis database. Minor packages like flask_cors were also used to enable CORS methods for the API. We chose this technology because it's pretty easy to setup :)
Here is the architecture of the backend application:
.
├── Dockerfile
├── Dockerfile.dev
├── __pycache__
│ └── app.cpython-311.pyc
├── pyproject.toml
└── src
├── app.py
├── __pycache__
│ └── app.cpython-311.pyc
├── routes
│ ├── __init__.py
│ ├── process.py
│ ├── __pycache__
│ └── result.py
└── utils
├── __init__.py
├── __pycache__
├── rabbitMQ.py
└── redis.py
It took a little time and testing to get the communication between Redis and RabbitMQ but nothing too crazy.
Like the backend, the consumer was written in Python for the same reasons (it's easy). The packages used are pika and redis for communication with RabbitMQ and the Redis database, respectively.
Here is the (awesome) architecture of the consumer application:
.
├── app.py
├── Dockerfile
└── Dockerfile.dev
Just like for the Backend, we took some time to set the communications between the app and Redis and RabbitMQ.
Setting up the RabbitMQ service was quick. We simply created a service using pre-existing RabbitMQ images.
Similar to RabbitMQ, the Redis database was set up by adding a service in the docker-compose.yaml file using an existing image.
So you don't want to read all our README, you meanie ~
![]()
Well, that's okay~ You don't want to lose some precious time after all, uwu
To start our app localy in dev mode, you only need to run
docker compose up
You wanna start it in production mode locally ? Then use
docker compose -f docker-compose.prod.yaml up
That's it ! You can now test our app locally
As a developer, we want things to be version controlled, even to the commands we use to build and push. To achieve that, we've been using a Makefile. It consists of 3 main commands :
- init : Allows you to login into gcloud and auto configuration for our project.
- build-images : Will build each image and tag them appropriately
- push-images : Will push each image on the configured project in
europe-west1-docker.pkg.dev
Also we've added a trivy image scan analysis but we did not use it intensively.
Using our awesome makefile make it easy to push our images to the repo.
If you already did the init step, you only have to do the following
make build-images
make push-images
Since we need to create a calculator, we must design it. An obvious design that comes to mind is that of Numworks calculators. Arno spent an hour creating a reproduction on Figma that just needs to be reproduced in code. Here is the result:
On the left, the real one; on the right, the reproduction.
We decided to use flask-restful to create our API.
pip install flask-restful
pip install redisGet
curl -X GET 0.0.0.0:5000/api/v1/result?id=[REQUEST_ID]"
Post
curl -X POST 0.0.0.0:5000/api/v1/process -H "Content-Type: application/json" --data '{"calculation":"[CALCULATION]"}'
virtualenv venv
source venv/bin/activate
