HellcatAPI
A backend api framework build with java 17. Raw HTTP server — zero frameworks, zero abstraction layers. You write routes, HellcatAPI handles everything else.
Getting Started
HellcatAPI requires Java 17 or higher and Maven 3.6+. Clone the repository, configure your server, and run.
Requirements
Runtime
Java 17 or higher (LTS recommended). OpenJDK or any compatible JVM.
Build Tool
Apache Maven 3.6 or higher. All dependencies are resolved via pom.xml.
Database
SQLite is bundled by default. PostgreSQL or MySQL require a JDBC driver swap.
OS
Linux, macOS, or Windows. Works anywhere a JVM runs.
Build & Run
git clone https://github.com/MatrixTM26/HellcatAPI.git
cd HellcatAPI
mvn clean package -q
java -jar HellcatAPI.jar
Minimal Application
Everything starts from HellcatApp. Pass your secret key as the first argument.
HellcatApp App = new HellcatApp("your-secret-key");
App.Get("/hello", Req ->
App.Json(Map.of("message", "Hello World"))
);
App.Run();
0.0.0.0:9926 unless overridden in server.properties.
Project Structure
All core logic lives under src/main/java/hellcat/core/. The entry point is TestApi.java.
app/
HellcatApp — main application class and entry point wrapper.
server/
Raw HTTP server, connection handler, and server logger.
router/
Route registration, matching, and path parameter parsing.
request/
Request parser, request object, and uploaded file model.
response/
Response builder and streaming response support.
middleware/
Middleware interface and all built-in middleware implementations.
template/
Lightweight Jinja2-like template engine.
db/
Database connection pool, query builder, and transaction context.
lib/
Logger utility and server config loader.
Configuration
Edit server.properties in the project root before running. All settings are optional — defaults are production-safe.
server.host=0.0.0.0
server.port=9926
server.debug=false
server.template.dir=templates
server.static.dir=static
server.static.url=/static
| Key | Default | Description |
|---|---|---|
| server.host | 0.0.0.0 | Bind address for the HTTP server |
| server.port | 9926 | TCP port the server listens on |
| server.debug | false | Enable verbose debug logging (true / false) |
| server.template.dir | templates | Directory for HTML template files |
| server.static.dir | static | Directory for static file assets |
| server.static.url | /static | URL prefix for serving static files |
Routing
Routes are registered on the HellcatApp instance. Handlers receive a HellcatRequest and must return a response object.
HTTP Method Shortcuts
App.Get("/hello", Req ->
App.Json(Map.of("Message", "Hello World"))
);
App.Post("/echo", Req -> {
Map<String, Object> Body = Req.GetJson();
return App.Json(Body);
});
App.Put("/item", Req -> App.Json(Map.of("updated", true)));
App.Delete("/item", Req -> App.Json(Map.of("deleted", true)));
App.Patch("/item", Req -> App.Json(Map.of("patched", true)));
Path Parameters
Use <type:Name> syntax. Supported types: int, str, float, path.
App.Get("/users/<int:Id>", Req -> {
int Id = Integer.parseInt(Req.PathParams.get("Id"));
return App.Json(Map.of("Id", Id));
});
App.Get("/files/<path:FilePath>", Req -> {
String FilePath = Req.PathParams.get("FilePath");
return App.Text(FilePath, 200);
});
Multi-Method Route
App.Route("/multi", List.of("GET", "POST"), Req ->
App.Json(Map.of("Method", Req.Method))
);
Middleware
Middleware intercepts every request before it reaches the route handler. Use built-in helpers or provide a custom lambda.
Built-in Middleware
// CORS — allow origins, credentials flag
App.UseCors(List.of("*"), false);
// Rate limiting — 100 requests per 60 seconds
App.UseRateLimit(100, 60);
// Adds security headers (X-Content-Type, X-Frame-Options, etc.)
App.UseSecurityHeaders();
// Gzip compress responses over 1024 bytes
App.UseGzip(1024);
// Reject bodies larger than 10 MB
App.UseBodySizeLimit(10 * 1024 * 1024);
Custom Middleware (Global)
App.UseMiddleware((Req, Next) -> {
long Start = System.currentTimeMillis();
Object Resp = Next.apply(Req);
System.out.println("Duration: " + (System.currentTimeMillis() - Start) + "ms");
return Resp;
});
Route-Level Middleware
App.Post("/secure", Handler, List.of(RequireAuthMiddleware));
Request Object
Every route handler receives a HellcatRequest instance. It contains all parsed request data.
Fields
Methods
Req.GetJson() // parse body as JSON → Map<String, Object>
Req.GetQuery("page", "1") // query param with default fallback
Req.GetHeader("Authorization") // get a specific request header
Req.GetRemoteIp() // client IP address
Req.IsJson() // true if Content-Type is application/json
Req.IsForm() // true if Content-Type is application/x-www-form-urlencoded
Req.IsMultipart() // true if Content-Type is multipart/form-data
Response Helpers
All response helpers are methods on the HellcatApp instance. Each returns a response object that the route handler must return.
| Method | Status | Description |
|---|---|---|
| App.Json(data) | 200 | JSON response from any object or Map |
| App.Json(data, 201) | custom | JSON with explicit HTTP status code |
| App.Html(html) | 200 | Raw HTML string response |
| App.Text(text, 200) | custom | Plain text response with status |
| App.Redirect(path) | 302 | HTTP redirect to another path |
| App.Redirect(path, 301) | custom | Redirect with explicit status (301, 302, etc.) |
| App.Error(msg, 404) | custom | JSON error with message and status |
| App.Error(msg, 422, details) | custom | JSON error with additional detail map |
| App.File(path, name) | 200 | Serve a file as a download attachment |
| App.Stream(supplier, type) | 200 | Streaming response (SSE, chunked transfer) |
| App.Render(template, ctx) | 200 | Render a template with a context map |
Usage Examples
App.Json(Map.of("status", "ok"))
App.Json(userList, 200)
App.Html("<h1>Hello</h1>")
App.Text("plain text", 200)
App.Redirect("/login")
App.Redirect("/login", 301)
App.Error("Not found", 404)
App.Error("Validation failed", 422, Map.of("field", "email"))
App.File("report.pdf", "download.pdf")
App.Stream(() -> chunks, "text/event-stream")
App.Render("index.html", Map.of("title", "HellcatAPI"))
Template Engine
HellcatAPI ships with a lightweight Jinja2-like template engine. Templates are stored in the templates/ directory and rendered with App.Render().
Rendering a Template
App.Get("/", Req ->
App.Render("index.html", Map.of(
"Title", "HellcatAPI",
"Message", "Server is running!"
))
);
Supported Syntax
| Tag | Description |
|---|---|
| {{ variable }} | Output a variable value (HTML-escaped) |
| {{ object.field }} | Output a nested object field |
| {{ value | raw }} | Output raw HTML without escaping |
| {% if condition %} ... {% endif %} | Conditional block |
| {% for item in items %} ... {% endfor %} | Loop over a collection |
| {% extends "base.html" %} | Extend a base template layout |
| {% block content %} ... {% endblock %} | Define or override a named block |
| {% include "partial.html" %} | Include another template file inline |
| {# comment #} | Template comment — not rendered in output |
Example Template
<!-- templates/index.html -->
{% extends "base.html" %}
{% block content %}
<h1>{{ Title }}</h1>
<p>{{ Message }}</p>
{% if Users %}
{% for User in Users %}
<div>{{ User.Name }} — {{ User.Email }}</div>
{% endfor %}
{% endif %}
{% endblock %}
Database
HellcatAPI bundles SQLite via HellcatDB. Swap to PostgreSQL or MySQL by replacing the JDBC driver in pom.xml.
Initialization
Map<String, String> Migrations = new LinkedHashMap<>();
Migrations.put("001_create_users",
"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)");
HellcatDB DB = new HellcatDB("app.db", 10, Migrations);
LinkedHashMap to ensure execution order. Keys are unique migration identifiers.
Query Builder
// Fetch all matching rows
DB.Table("users").WhereEq("role", "admin").OrderBy("id").All();
// Fetch the first matching row
DB.Table("users").WhereEq("id", 1).First();
// Count rows
DB.Table("users").Count();
// LIKE search with pagination
DB.Table("users").WhereLike("name", "%Tom%").Paginate(1, 20);
Write Operations
// Insert a row
DB.InsertRow("users", Map.of(
"name", "Tom",
"email", "tom@example.com"
));
// Update matching rows
DB.Table("users").WhereEq("id", 1).Update(Map.of("name", "Bob"));
// Delete matching rows
DB.Table("users").WhereEq("id", 1).Delete();
Transactions
try (HellcatTransactionContext Tx = DB.Transaction()) {
Tx.Execute(
"UPDATE products SET stock = stock - ? WHERE id = ?", 1, 5
);
long OrderId = Tx.Insert(
"INSERT INTO orders (product_id, qty) VALUES (?, ?)", 5, 1
);
Tx.Commit();
}
JWT & Sessions
HellcatAPI includes built-in JWT signing/verification and a simple session system. The secret key is the one passed to HellcatApp.
JSON Web Tokens
// Sign a token with a payload, expiry in seconds
String Token = App.CreateJwt(
Map.of("UserId", 1, "Role", "admin"),
3600
);
// Verify and decode a token
Map<String, Object> Payload = App.DecodeJwt(Token);
Sessions
// Read session from request cookies
Map<String, Object> Session = App.GetSession(Req);
// Write session data into a response (null = use default expiry)
App.SaveSession(Response, Map.of("UserId", 1), null);
SaveSession, or null for a browser-session cookie.
Sub-Routers
Group routes under a common prefix using HellcatRouter. Attach it to the main app with App.Include().
HellcatRouter Api = new HellcatRouter("/api/v1");
Api.Get("/health", Req ->
App.Json(Map.of("Status", "ok"))
);
Api.Get("/users", Req ->
App.Json(DB.Table("users").All())
);
Api.Post("/users", Req -> {
Map<String, Object> Body = Req.GetJson();
DB.InsertRow("users", Body);
return App.Json(Map.of("created", true), 201);
});
App.Include(Api);
Routes registered on Api are resolved as /api/v1/health, /api/v1/users, etc.
Error Handlers
Register custom handlers for HTTP error codes. The handler receives the original request and the error object.
App.ErrorHandler(404, (Req, Err) ->
App.Json(Map.of(
"Error", true,
"Message", "Route not found",
"Path", Req.Path
), 404)
);
App.ErrorHandler(500, (Req, Err) ->
App.Json(Map.of(
"Error", true,
"Message", "Internal server error"
), 500)
);
App.ErrorHandler(429, (Req, Err) ->
App.Json(Map.of(
"Error", true,
"Message", "Rate limit exceeded"
), 429)
);
Full Reference
HellcatApp Methods
HellcatDB Methods
Dependencies
HellcatAPI intentionally keeps its dependency count minimal. Add these to your pom.xml.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.45.3.0</version>
</dependency>
HellcatDB accordingly. No other changes required.