My Projects
This page showcases some of my biggest software projects I have built. Check my GitHub repositories here for a complete list of all my personal projects and works.
In-memory key-value data store
HakjDB in-memory key-value data store. GitHub repository here. Blog post here.
Quoted from the README:
HakjDB is a simple in-memory key-value data store that was built as an educative hobby project. It is written in the Go programming language.
HakjDB allows you to store key-value pairs of different data types in namespaces called databases. The data is stored in the server’s memory.
HakjDB uses a simple client-server model, and has a well-defined and documented gRPC API. It can be used as a temporary database, session storage or cache. It may not be suitable for advanced needs, and does not offer data persistence on disk.
Data is stored at keys of different types. Each data type allows you to store different kind of data such as string values or objects.
Instances are easily configurable with command line flags, environment variables and a simple YAML file.
This project also includes a CLI tool called hakjctl
and a cross-platform desktop app GUI tool called hakjdb-gui
that allow the user to control and interact with server instances. The desktop app’s GitHub repo is here. The CLI tool is programmed in Go and the desktop app in TypeScript and Rust using Tauri framework.
Below is a preview of the GUI tool
This project has a lot of features and has grown to be my largest project so far. It started as a simple project to better learn and understand how key-value databases like Redis and etcd work, but after some time I found myself working on it for over half a year. Even now, it can still be extended a lot. This project increased my Go programming skills and knowledge considerably, and I became more confident working on a large code base. I learned to build an advanced server application, gRPC API, CI/CD pipeline with GitHub Actions, TLS with client cert auth and so much more.
Some of the main features include:
- gRPC API with Protobuf
- Authentication with JWT
- TLS and optional mTLS
- Custom key-value database library
- Custom logging library with log levels
- Log file
- Unit and integration tests
- Docker support
- Configurations with command line flags, environment variables and a YAML file
- Client connection tracking and limiting max active connections
- Reloading configurations at runtime
Below is a diagram that shows the architecture
gRPC microservices
Example microservices project that uses gRPC for inter-service communication. GitHub repository here. Blog post series here.
The goal was to showcase synchronous gRPC usage in microservices and to expand my knowledge and skills about microservices, Go and gRPC. I built this project as part of my thesis that discusses the benefits of using gRPC for synchronous microservice communication. The thesis can be accessed here. It explains the whole development process, design decisions, testing and project results.
The project consists of 3 microservices programmed in Go that each was built using hexagonal architecture. The services communicate via a synchronous call chain using Remote Procedure Calls. Each service can be configured independently using environment variables and YAML files. gRPC APIs are defined with Protobuf in .proto files. These files along with the generated gRPC source codes are organized in a separate Git repository here. The generated source codes are external Go dependencies that are versioned so the microservices can consume them.
This project was very useful and taught me a lot. I learned more about 12-factor method, using gRPC and Protobuf, architecting and building microservices, designing a simple synchronous IPC call chain, and to develop backend services with hexagonal architecture.
Terminal game
TUI game for the terminal. GitHub repository here.
This project is a terminal based RPG game where the player fights enemies in randomly generated dungeons. No mouse required. Player plays with keyboard in a fully interactive TUI mode.
The game is programmed in the Rust language and requires only the game binary to play. When the user runs the binary, the game starts and renders a TUI window in the terminal window where the game was run. There is no game engine used. The game is built from scratch using Rust’s crossterm library to render TUI menus. Game progress will be saved to a save file which is loaded every time the game is started.
The game has a shell script which allows to easily make new releases with built binaries for Linux and Windows. It also creates a checksums.txt file with SHA256 hashes for the compressed binaries so the users can verify they download the right files. Game binaries can be downloaded from the GitHub repository releases page or installed with Cargo package manager. The game is published on crates.io, Rust’s official package registry.
Below is a short gameplay preview of the game
Below is a short gameplay preview of a boss fight
The game generates dungeon floors with randomly generated rooms. Rooms are connected together in 2D grid style. Each room has X and Y coordinates. The start room has coordinates (0,0). Each room can have at most 2 adjacent rooms. Directions are up, down, right and left. Rooms are always generated in up, right or left direction from the previous room.
Here is how the dungeon floor generation algorithm works:
- Create start room
- Create the second room
- Connect the start room and the second room
- Create a random possible room
- Connect the current room and the created room
- Repeat until threshold for the boss room is reached
- Boss entrance room becomes a possible room to be randomized
- Create random rooms until boss entrance room is randomized
- Stop creating rooms
- randomize treasure chest to one random room
- randomize enemies to random rooms (1 enemy per room)
- randomize boss enemy
- randomize shop items
This project was a lot of fun to build. Rust is a challenging but rewarding programming language. It has really good performance and the compiler tells you about errors and mistakes you have in your code. This continuous compiler feedback I have in my code editor is one of my favorite parts of Rust. This project improved my programming skills and logical thinking a lot. Building a game from scratch is also a really good way to expand your knowledge about data structures and algorithms.
Authentication microservice
Authentication microservice. ASP.NET Core, Docker, k8s. Includes CLI tool built with Rust. GitHub repository here.
This project is an authentication microservice built with C# programming language and ASP.NET Core framework. It has support for Docker containers and Docker Compose. Docker image is published in GitHub Container registry. The project also has Kubernetes resource declarations in YAML files to deploy it to a local Kubernetes cluster.
The microservice can authenticate users with JWT. The user sends credentials (username and password) to the login endpoint and the service returns a JWT access token if login was successful. After this the user can access the user database with the JWT token to fetch all users via an API endpoint.
The microservice has two different types of APIs: REST and gRPC. They have RBAC (Role based access control). Only admin role can fetch users. The database is a PostgreSQL relational database that I ran in a Docker container during development. The microservice uses the database with .NET Entity Framework which provides an easy to use ORM. Users are managed with ASP.NET Core Identity. Passwords are stored using BCrypt hashing algorithm and pepper. The pepper is a secret value that is added to passwords before hashing them. This adds some extra security but could cause problems if the secret value is lost.
The project also includes a CLI tool that is programmed in Rust. The microservice can be used with this tool. It can login the user, store the JWT access token in a local token cache file and show all the users’ information including roles. The tool can use both the REST and gRPC API.
I built this project as the final project of one of my college courses. It contains a full walkthrough of the project documented in Markdown. It can be read here. Note that it is written in Finnish and not English. The project was deployed to CSC Rahti cloud service which used OKD (community distribution of Kubernetes) as its underlying platform. This was a great platform for learning about cloud deployment with containers.