We use backend frameworks every day. But have you ever wondered how they're built?
This project is my attempt to answer that question.
Java Micro Backend Framework is a lightweight HTTP framework built completely from scratch using Java's standard library. It implements many of the core concepts behind modern backend frameworks—including routing, middleware, request/response abstractions, authentication, and static file serving—to provide a hands-on understanding of how web frameworks work internally.
Note: This is an educational project built to explore backend fundamentals. It is not intended for production use.
-
- Dynamic Path Parameters
- Query Parameters
-
- Logging
- Authentication
- CORS
- Exception Handling
- Built directly on raw TCP sockets
- HTTP/1.0 & HTTP/1.1 support
- Keep-Alive connections
- Concurrent requests handling (Virtual Threads)
- Custom routing system
- Dynamic path parameters
- Query parameter parsing
- Middleware pipeline
- Authentication middleware
- Logging middleware
- Exception middleware
- CORS middleware
- Static file server
- File CRUD operations
- JSON response support
- MIME type detection
- HEAD request support
- Clean Request & Response abstractions
- Zero external libraries
Client
│
▼
TCP Connection
│
▼
Parse HTTP Request
│
▼
Resolve Route
┌──────────┴──────────┐
│ │
▼ ▼
Static File Server Route Found
│
▼
Middleware Chain
│
┌────────────────────────────────────────────────────┐
│ Exception → Logging → CORS → Authentication │
└────────────────────────────────────────────────────┘
│
▼
Route Handler
│
▼
HTTP Response
Clone the repository:
git clone https://github.com/<your-username>/<repository>.git
cd <repository>Run the server:
java WebServer --directory filesThe server will start on:
http://localhost:5555
| Method | Endpoint | Description |
|---|---|---|
| GET | /hello |
Returns a plain text response |
| GET | /echo/{message} |
Echoes the supplied message |
| GET | /user-agent |
Returns the client's User-Agent |
| GET | /search?query=&page= |
Demonstrates query parameter parsing |
| GET | /files/{filename} |
Downloads a file (Authentication required) |
| POST | /files/{filename} |
Creates a new file |
| PUT | /files/{filename} |
Updates an existing file |
| DELETE | /files/{filename} |
Deletes a file |
| HEAD | /files/{filename} |
Returns response headers only |
If no route matches, the framework attempts to serve a static file from the public/ directory.
Routes are registered with the router by specifying an HTTP method and a URL pattern.
Example:
router.get("/hello", Handlers::helloHandler, false);
router.post("/files/{filename}", Handlers::createFileHandler, false);Each route consists of:
HTTP_METHOD + URL Pattern + Handler + Authentication Flag
Path parameters allow parts of the URL to be captured dynamically.
Example:
GET /files/{filename}
Request:
GET /files/readme.txt
Inside the handler:
String filename = request.getPathParameter("filename");Query parameters are automatically parsed into a map.
Request:
GET /search?query=java&page=2
Inside the handler:
String query = request.getQueryParameters().getOrDefault("query", "");
String page = request.getQueryParameters().getOrDefault("page", "1");Every incoming request is represented by a Request object.
It provides access to:
- HTTP method
- URL
- HTTP version
- Headers
- Body
- Path parameters
- Query parameters
- Client IP
- Matched route
Examples:
request.getVerb();
request.getURL();
request.getRequestHeaders();
request.getRequestBody();
request.getPathParameter("filename");
request.getQueryParameters();
request.getClientIP();Handlers build responses using the Response abstraction.
Plain text:
response.text("Hello World");JSON:
response.json(Map.of(
"message", "Hello World"
));Custom status code:
response.setStatusCode("404");
response.text("Not Found");Response headers:
response.addResponseHeader("Content-Type", "text/plain");Every request flows through a configurable middleware pipeline before reaching the handler.
Request
│
▼
Exception Middleware
│
▼
Logging Middleware
│
▼
CORS Middleware
│
▼
Authentication Middleware
│
▼
Route Handler
│
▼
Response
Middleware registration:
use(new ExceptionMiddleware());
use(new LoggingMiddleware());
use(new CorsMiddleware());
use(new AuthenticationMiddleware());Current middleware includes:
- Exception handling
- Structured request logging
- CORS support
- Token-based authentication
When no registered route matches an incoming request, the framework attempts to serve a file from the public/ directory.
Examples:
GET /
serves
public/index.html
while
GET /css/styles.css
serves
public/css/styles.css
The framework automatically determines the appropriate MIME type based on the file extension.
src
├── middleware
│ ├── AuthenticationMiddleware
│ ├── CorsMiddleware
│ ├── ExceptionMiddleware
│ ├── LoggingMiddleware
│ ├── Middleware
│ └── MiddlewareChain
│
├── serialization
│ └── JsonSerializer
│
└── webServer
├── WebServer
├── Router
├── Route
├── Request
├── Response
├── RouteHandler
├── StaticFileServer
└── Handlers
Although the project has achieved its educational goals, there are many directions it could be extended:
- Recursive JSON serialization
- Automatic HEAD → GET fallback
- Better HTTP request validation
- Additional MIME types
- HTTP caching
- Chunked Transfer Encoding
- GZIP compression
- TLS / HTTPS support
This project wasn't built to replace Spring Boot or other mature frameworks.
It was built to answer a simple question:
"How do backend frameworks actually work?"
The best way to understand that wasn't by reading documentation—it was by building one.
Modern backend frameworks make web development incredibly productive, but they also abstract away a tremendous amount of engineering.
Building this micro backend framework from scratch was an opportunity to explore those internals—from parsing raw HTTP requests to designing a middleware pipeline and routing system—and gain a deeper understanding of the technologies we use every day.
If you found this project interesting or have suggestions for improvements, feel free to open an issue or leave a ⭐.