Init 1
Rust code platform - part 1
posted on 2024 Sep 22Small project idea to have some fun with Rust and try to build something as close as possible to being production-ready. This project also aims to dabble a bit with the language on the web backend side.
Constraints
- Minimal requirements
- Observability
The idea I was thinking about is a simplified coding platform in the neetcode style. The system will be seeded with a set of problems, users can register, admin users can also upload new problems (although authentication and authorization may be out of scope for the time being). Problems can be run inside self-contained environments (think about Docker containers, maybe providing a subset of pre-built images for each programming language offered, C, C++, Python and Go can be a good starting point).
Tech stack
Rust is the chosen language for this project, I’m not really familiar yet with
the current trends and best practices, last time I checked actix
and sqlx
were the backbone of any backend application. After some recognition work, this
is what I came up with:
- Actix - REST APIs
- Postgres - Diesel or sqlx
- Prometheus
- Grafana
Axum and Pavex also look interesting, however it’s not the point of the project
to explore different frameworks to achieve the same result, it’s the overall
practicality of Rust for the web that I’d like to refresh. We’re probably gonna
use Docker and docker-compose
to run the entire environment locally in dev,
it’s a convenient way to emulate a staging/prod environment without the hassle
of deploying stuff to an Heroku dyno or any other cloud provider.
Data model
The main entity in the application is represented by the problems. They will include a title, a description and some metadata such as the category, the difficulty and a skeleton based on the language, something like
{
title: "Two Sum",
description: "Given an array of integers `nums` and an integer `target`, return the integers `i` and `j` such that `nums[i] + nums[j] = target`..",
categories: ["arrays"],
difficulty: "easy",
starting_snippets: {
"c": "int *two_sum(int *nums, size_t len, int target) ..",
"python": "def two_sum(nums, target)..."
},
solved: "false"
}
To start very simple they could be stored in a JSON or YAML static file on
a filesystem, I prefer to store them in the DB to allow easier query
capabilities and at a later stage, extensibility and upload of new problems.
Every problem can have multiple solutions clearly, so that would be another
table to be joined as a has_many
relationship with the problem.
To cut short, a loosely detailed definition of the schemas we’re going to need:
- User
- email: string
- nickname: string
- has_many(Problem)
- Problem
- title: string
- description: string
- categories: list(string)
- difficulty: string
- starting_snippets: map
- test_cases: list(string)
- solved: boolean
- editorial: map
- has_many(Solution)
- Solution
- description: string
- snippet: string
Keeping things simple as a first draft, we can assume that the images repositories with various metadata (e.g. languages versions, OS etc) can be stored locally in a static JSON or YAML file.
APIs
It will be a pure REST application, no frontend at all, but it should provide all the required to be easily integrated in a JS app.
ASSUMPION we can start with a set of problems and editorial pre-seeded in the system, on a later stage we can decide to increment the functionalities and allow users roles, auth, and upload of new problems, contests maybe and notifications to subscribed users.
User management
Creation of a new user and retrieve of the user, probably with some sort of stats and solved problems etc.
- POST
/v1/users
- GET
/v1/users/:user_id
Problems management
Creation of a new problem, listing of all the problems, probably opt-in filters by category, difficulty and pagination etc; retrieve of a specific problem by ID. Definitely submission of a solution to any given problem and listing.
- GET
/v1/problems/:problem_id
- GET
/v1/problems
- POST
/v1/problems/:problem_id
Authentication & RBAC
TBD