[PROJECT]
krustie
0.3.0
An experimental backend HTTP framework built in Rust from the TCP layer up, with a custom parser, middleware pipeline, and an immutable request lifecycle.
[YEAR]
2024
[TYPE]
Published Package
[STATUS]
Ongoing
Key Capabilities
- Custom HTTP parser
- Dynamic routing with parameters
- Query parsing
- Middleware pipeline execution
- Immutable request lifecycle
- Built-in rate limiting & gzip compression
- Static file serving
- Integration testing utilities
Summary
It started as a minimal HTTP server implementation that works at the TCP level, and gradually evolved into a structured backend framework with an immutable request lifecycle as I explored routing, middleware design, and request lifecycle management.
use krustie::{ Router, Server, StatusCode };
fn main() {
let mut server = Server::create();
let mut router = Router::new();
router.get("/", |_, res| {
res.status(StatusCode::Ok).body_text("Hello World!");
});
server.use_handler(router);
server.listen(8080);
}
At first my plan was a simple HTTP server with a few basic routes. While I was working on it I started to have some ideas about how it can be turned into an http framework.
First I created the foundation of the project, then I started to add more features such as routing with queries /user?sort=DESC and dynamic parameters /user/:id. I had to rewrite the whole routing logic because the first iteration had no room to grow — it was just comparing strings from the client against the routes.
Next step was to add the middleware support. I had to rewrite the routing logic again, this time to create a clear separation between the router and the endpoint pipeline. Architecture-wise router, middleware and endpoint are all handlers. Router is a handler that routes the request to the correct part of the pipeline. Middleware is a handler that runs before or after the endpoint. And endpoint is the handler that actually handles what is going to happen.
While I was doing it I decided to make request object immutable. It was hard to persevere with this decision but I was aiming to create a safe and easy to use framework to decrease the possibility of bugs.
TCP Connection → HTTP Parser → Router → Middleware Pipeline → Handler → Response
After that I implemented some basic middlewares such as static file serving, rate limiting, gzip compression and json parser/serializer to see how the middleware system works. While doing it I realized there were still some features missing to create these middlewares. I added the missing features but I believe that it still needs some improvements.
I wrote some tests because while I was working on the project I had some issues with the http parser time to time. Tests helped me to fix them so much faster. And as a final test, I decided to create a basic web server. After I developed and ran it, I found out that some of the parts don’t work as expected. So I added some basic testing tools to test the app as well. It turned out great and helped me to analyze the issues better.
Building this made one thing obvious: all web infrastructure is just a bunch of parsers packed together.
The current architecture was kept synchronous to understand the fundamentals first. I’m planning to add multithreading and asynchronous methods support in the future.
Featured Projects
Graduation Project
A greenhouse monitoring and control system that uses Visible Light Communication to transmit sensor data between Arduino nodes, with a React-based web dashboard for real-time monitoring.
View Project >>mrcn.tr
Personal website built with Astro, Tailwind (and love). Used features such as Content Collections and Font Provider API.
View Project >>Redis Clone
A Redis-compatible server implementing RESP protocol over TCP. Focused on in-memory data structures and protocol parsing.
View Project >>