Skip to content

jhanvi857/coreHTTP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

148 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NioFlow

NioFlow Logo

A lightweight Java 17 HTTP micro-framework with explicit routing, middleware composition, and production-focused runtime controls.

Java Maven Coverage License Release NPM Version

NioFlow is designed around one principle: make HTTP internals understandable without sacrificing production behavior. Instead of hiding complexity behind annotations and reflection-heavy bootstrapping, NioFlow keeps transport, parsing, routing, middleware, and error handling explicit and testable.


Table of Contents


What NioFlow Is

NioFlow is a two-part system:

  1. nioflow-framework: reusable HTTP framework module.
  2. task-planner-app: reference application that demonstrates how to use the framework in a real service.

It sits between "build a server from scratch" and "adopt a massive framework":

Concern NioFlow Approach Why It Matters
Connection accept NIO selector loop High connection scalability with low idle overhead
Request handling Bounded worker pool Predictable behavior under load
Routing Explicit code-based routes Easy debugging and refactoring
Middleware Global + route-group scoped Clear policy layering (auth, rate limits, CORS)
Errors Per-type handlers + global fallback No stack trace leakage
Shutdown Graceful draining via drainAndStop Safer rolling restarts

Key Capabilities

1. Explicit Route Registration

NioFlowApp app = new NioFlowApp();

app.get("/", ctx -> ctx.send("Hello"));
app.get("/api/tasks/:id", ctx -> {
    long id = ctx.pathParamAsLong("id"); // Safe numeric parsing
    // ...
});

app.group("/api/admin", group -> {
    group.use(new AuthMiddleware());
    group.get("/stats", adminController::stats);
});

2. Middleware Pipeline

app.use(new LoggerMiddleware());
app.use(new CorsMiddleware("https://yourdomain.com"));
app.use(new RateLimitMiddleware(100, 10_000));

Middleware executes in registration order and is wrapped around each resolved route handler.

3. Global Error Control

app.exception(IllegalArgumentException.class, (e, ctx) -> {
    ctx.status(400).json(Map.of("error", "Bad Request", "details", e.getMessage()));
});

app.onError((err, ctx) -> {
    ctx.status(500).json(Map.of("error", "Internal Server Error"));
});

4. TLS Entry Point + Graceful Stop

app.listenSecure(443, "keystore.jks", "changeit");

Runtime.getRuntime().addShutdownHook(
    new Thread(() -> app.drainAndStop(30, TimeUnit.SECONDS))
);

Install CLI (Recommended)

The NioFlow CLI handles scaffolding, environment setup, and hot-reloading for you. Requires Node.js (for the installer) and JDK 17+.

npm install -g @jhanvi857/nioflow-cli

# Create a project
nioflow new my-app
cd my-app

# Start with hot-reload
nioflow dev

Note: Node.js is only used to distribute the CLI. Your application runs purely on Java.

Manual Setup (Without CLI)

Prerequisites

  • JDK 17+
  • Maven 3.9+

0. Configure environment

Create a local .env from the example and set a strong JWT secret:

cp .env.example .env

Windows PowerShell alternative:

Copy-Item .env.example .env

At minimum, set:

  • JWT_SECRET (32+ characters)
  • NIOFLOW_CORS_ORIGIN (frontend origin)
  • DB_PASS (if NIOFLOW_ENABLE_DB=true)

1. Build all modules

# From repository root
./mvnw clean test

Windows PowerShell alternative:

.\mvn.ps1 clean test

2. Run the reference app

./mvnw exec:java -pl task-planner-app \
  -Dexec.mainClass=io.github.jhanvi857.taskplanner.DemoApplication \
  -Dnioflow.jwtSecret=your-very-long-secret-at-least-32-chars

3. Verify endpoints

curl http://localhost:8080/_health
curl http://localhost:8080/_ready
curl http://localhost:8080/metrics
curl http://localhost:8080/api/tasks/

Expected behavior:

  • /_health returns 200 with JSON payload.
  • /_ready returns 200 when dependencies are ready.
  • /metrics returns 200 (requires NIOFLOW_METRICS_TOKEN if configured).
  • /_replay returns 401 without bearer token (now auth-gated).
  • /api/tasks/ returns 401 without bearer token.

Framework Programming Model

App Bootstrap Pattern

public class MyService {
    public static void main(String[] args) {
        NioFlowApp app = new NioFlowApp();

        app.use(new LoggerMiddleware());
        app.use(new CorsMiddleware("https://yourdomain.com"));

        app.get("/", ctx -> ctx.send("Service up"));

        app.group("/api/private", group -> {
            group.use(new AuthMiddleware());
            group.get("/profile", profileController::getProfile);
        });

        app.onError((err, ctx) -> {
            ctx.status(500).json(Map.of("error", "Internal Server Error"));
        });

        Runtime.getRuntime().addShutdownHook(
            new Thread(() -> app.drainAndStop(30, TimeUnit.SECONDS))
        );

        app.listen(8080);
    }
}

Route Parameters and Context API

app.get("/api/tasks/:id", ctx -> {
    long id = ctx.pathParamAsLong("id"); // Type-safe and injection-resistant
    String auth = ctx.header("Authorization");

    ctx.status(200).json(Map.of(
        "taskId", id,
        "authorized", auth != null
    ));
});

Async Repository Pattern (JDBC Offload)

public CompletableFuture<Optional<Task>> findById(Long id) {
    return CompletableFuture.supplyAsync(() -> {
        // Blocking JDBC work isolated in dedicated DB executor
        // so request workers are not permanently blocked by DB I/O.
    }, dbExecutor);
}

Advanced Feature Pack

NioFlow now includes six opt-in features designed for small teams operating production services without heavy platform infrastructure.

1. ChaosMiddleware (controlled fault injection)

app.use(
    new ChaosMiddleware()
        .latency(200, 0.10)
        .error(500, 0.05)
        .drop(0.01)
);
  • Guarded by NIOFLOW_CHAOS_ENABLED=true.
  • Logs each injected fault with route and path.
  • Supports composable latency, error, and drop behavior.

2. Per-route observability and protection (fluent API)

app.get("/api/orders", ordersController::list)
   .timeout(2000)
   .rateLimit(50, 10_000);
  • Per-route request/error counters.
  • Per-route p50/p95/p99 latency (sliding in-memory window).
  • Route-scoped timeout and route-scoped rate limit.

3. Request hedging for tail-latency reduction

app.get("/api/search", searchController::search)
   .hedge(100);
  • Fires a backup execution when primary crosses threshold.
  • Returns first successful completion.
  • Hedge trigger count appears in route-level metrics.

4. Route-group scoped circuit breaker middleware

app.group("/api/downstream", group -> {
    group.use(new CircuitBreakerMiddleware()
        .threshold(0.5)
        .windowSize(20)
        .cooldown(10_000));

    group.get("/inventory", inventoryController::read);
});
  • CLOSED / OPEN / HALF_OPEN states.
  • OPEN returns 503 and Retry-After header.
  • Circuit state is exposed per route-group in /metrics output.

5. Request replay for fast debugging

app.enableReplay(50);
  • Guarded by NIOFLOW_REPLAY_ENABLED=true.
  • Captures recent requests in circular memory buffer.
  • GET /_replay lists recorded requests.
  • POST /_replay/:index replays through current live pipeline.
  • Sensitive headers (Authorization, Cookie, X-API-Key, Proxy-Authorization) are stripped automatically.
  • SECURITY: The replay endpoints are now protected by AuthMiddleware by default. Only authenticated users with valid JWTs can access request history.

6. Hot Reload (Watch Mode)

NioFlowApp.enableHotReload(DemoApplication.class, args);
  • Guarded by NIOFLOW_WATCH=true.
  • Monitors source directory for changes.
  • Automatically recompiles using Maven (mvn, mvnw, or mvn.ps1).
  • Restarts the application in a child process for near-instant developer feedback.

Architecture Deep Dive

Runtime Topology

graph TD
    C[Client] --> SEL[Selector Accept Loop]
    SEL --> ACC[Accept SocketChannel]
    ACC --> BLK[Configure blocking mode for worker parsing]
    BLK --> WP[Bounded Worker Pool]
    WP --> HP[HttpParser]
    HP --> RT[Router]
    RT --> MW[Middleware Chain: Logger, Tracing, CORS]
    MW --> CB{Circuit Breaker?}
    CB -- OPEN --> 503[503 Service Unavailable]
    CB -- CLOSED --> H[Route Handler]
    H --> RESP[HttpResponse]
    RESP --> C

    H --> DB[(PostgreSQL / Mongo / Redis)]
    H --> OT[OpenTelemetry Exporter]
    RT --> PLG[Plugins: HealthCheck, StaticFiles, Replay]
Loading

Request Lifecycle Sequence

sequenceDiagram
    participant Client
    participant Worker
    participant Router
    participant Middleware
    participant Handler

    Client->>Worker: TCP Connection
    Worker->>Worker: Parse HTTP Request
    Worker->>Router: Resolve Route
    alt Route Not Found
        Router-->>Client: 404 Not Found
    else Method Not Allowed
        Router-->>Client: 405 Method Not Allowed
    else Success
        Router->>Middleware: Execute Global + Group Hooks
        Middleware->>Handler: Execute Handler (wrapped in CB/Hedge)
        Handler-->>Client: 200/201/204 Response
    end
Loading

Threading Model

  • Accept path: NIO selector thread.
  • Request work path: bounded worker pool.
  • Database path: dedicated DB executor pool.

This split protects the server from unbounded queue growth and improves backpressure behavior under load.


Security Model

Authentication

  • Protected route groups use AuthMiddleware.
  • Token format: Authorization: Bearer <jwt>.
  • JWT key source: JWT_SECRET (env) or -Dnioflow.jwtSecret=....
  • Startup behavior in reference app: exits if JWT secret is missing or too short.

Request Hardening

Control v1.4.0 Hardening Behavior
Header size cap 8 KB maximum
Body size cap 10 MB maximum
HTTP Smuggling Rejects obfuscated Transfer-Encoding (e.g. "identity, chunked")
Injection Rejects CRLF in headers and Null bytes in paths
Rate limiting Hardened IP extraction (Socket Peer fallback)
JWT Security Mandatory issuer validation and high-entropy secret check
Error responses Sanitized with generic messages in production
Code Coverage 83.44% Instructions, 71.69% Branches (Enforced by JaCoCo)

Quality Assurance

NioFlow maintains a rigorous testing strategy to ensure framework stability and security. All pull requests are gated by a JaCoCo coverage check in the build pipeline.

Current Test Coverage (v1.4.0)

Package Instruction Coverage Branch Coverage Focus
.protocol ~89% ~89% HTTP Parsing & Smuggling defenses
.routing ~85% ~80% Route matching & parameter extraction
.middleware ~85% ~80% Auth, RateLimit, Metrics
.util ~92% ~85% JSON, Env, Internal helpers
.plugin ~75% ~70% StaticFiles, HealthChecks
TOTAL 83.44% 71.69% Project Baseline

Running Tests locally

To execute the full test suite and generate a coverage report:

mvn clean test

The report is generated at nioflow-framework/target/site/jacoco/index.html.

CORS Strategy

String corsOrigin = System.getenv("NIOFLOW_CORS_ORIGIN");
if (corsOrigin == null || corsOrigin.isBlank()) {
    corsOrigin = "http://localhost:3000";
}
app.use(new CorsMiddleware(corsOrigin));

For production, always set NIOFLOW_CORS_ORIGIN to your exact frontend origin.


Configuration Matrix

Variable / Property Required Default Purpose
PORT No 8080 Server port
JWT_SECRET Yes unless auth disabled None JWT secret used by AuthMiddleware
NIOFLOW_DISABLE_AUTH No false Disable JWT checks for protected groups (dev only)
NIOFLOW_CORS_ORIGIN Recommended http://localhost:3000 CORS allow-origin value
NIOFLOW_ENABLE_DB No false Enables DB-backed readiness checks and repository behavior
JDBC_URL If DB enabled jdbc:postgresql://localhost:5432/nioflow PostgreSQL URL
DB_USER If DB enabled postgres PostgreSQL user
DB_PASS If DB enabled None PostgreSQL password
MONGO_URI No None Optional MongoDB URI (enables initMongo)
NIOFLOW_THREADS / nioflow.threads No 64 Worker pool size in HttpServer
NIOFLOW_QUEUE_CAPACITY / nioflow.queueCapacity No 1000 Worker queue capacity for backpressure
NIOFLOW_SOCKET_TIMEOUT_MS / nioflow.socketTimeoutMs No 30000 Socket read timeout per connection
NIOFLOW_TLS_ENABLED No false Enable native TLS listener
NIOFLOW_TLS_KEYSTORE_PATH If TLS enabled None JKS keystore path
NIOFLOW_TLS_KEYSTORE_PASSWORD If TLS enabled None Keystore password
NIOFLOW_TLS_PORT No 8443 Native TLS listener port
NIOFLOW_EXPOSE_ERROR_DETAILS No false Include exception details in error payloads
NIOFLOW_STATIC_DIR / nioflow.staticDir No Auto-resolve Static files directory
NIOFLOW_CHAOS_ENABLED No false Enables ChaosMiddleware fault injection
NIOFLOW_REPLAY_ENABLED No false Enables enableReplay(...) endpoints
NIOFLOW_WATCH No false Enables nodemon-like hot reload (Watch Mode)
NIOFLOW_LOG_FORMAT No plain Set to json for structured logging
NIOFLOW_REDIS_URL No None Redis connection string for distributed rate limiting
NIOFLOW_TRACING_ENABLED No false Enables OpenTelemetry tracing
NIOFLOW_METRICS_TOKEN No None Optional bearer token gate for /metrics
NIOFLOW_JWT_EXPIRATION_MS No 900000 (15m) JWT access token lifetime
OTEL_EXPORTER_OTLP_ENDPOINT No http://localhost:4317 OTLP gRPC collector endpoint

Database Integration

NioFlow provides a centralized Database utility to manage your persistence layers with zero boilerplate.

1. PostgreSQL (Supabase / Local)

Initialize and get connections directly:

NioFlowApp app = new NioFlowApp();
// Reads JDBC_URL from .env
app.initPostgres(); 

try (Connection conn = Database.getPostgresConnection()) {
    // Standard JDBC logic
}

2. MongoDB (Atlas / Local, optional)

Initialize and access the document store:

// Reads MONGO_URI from .env
app.initMongo(); 

MongoClient mongo = Database.getMongoClient();
MongoDatabase db = mongo.getDatabase("nioflow");

Environment Variable Management

NioFlow includes a built-in Env utility that automatically loads configuration from a .env file in your project root. This ensures that sensitive keys (like Supabase secrets) remain safe and are not passed via command line arguments.

Example .env file:

JDBC_URL=jdbc:postgresql://your-db.supabase.co:5432/postgres
DB_USER=postgres
DB_PASS=your-password
JWT_SECRET=your-32-char-secret
PORT=8080

Deployment Guide

Build Artifacts

./mvnw package -DskipTests -pl task-planner-app -am

Primary runnable artifact:

task-planner-app/target/task-planner-app-1.0-SNAPSHOT-jar-with-dependencies.jar

Run as Plain JVM Service (non-Docker)

With the new .env support, you no longer need complex -D flags:

java -jar task-planner-app/target/task-planner-app-1.0-SNAPSHOT-jar-with-dependencies.jar

Production Checklist

  • Global onError handler registered.
  • Graceful shutdown hook registered.
  • Protected routes gated by AuthMiddleware.
  • JWT secret validated at startup.
  • Integration tests assert auth enforcement and observability endpoints.
  • Integration tests assert 404 vs 405 distinction.
  • Integration tests assert middleware ordering and header preservation.
  • Integration tests assert circuit breaker state transitions (CLOSED → OPEN → HALF_OPEN → CLOSED).
  • TLS plan finalized (listenSecure or reverse proxy termination).
  • Runtime sizing validated with reproducible load testing script (scripts/k6-load-test.js).
  • Vulnerability scanning is enforced in CI for push/PR (OWASP Dependency Check).

Performance Benchmarks

NioFlow is designed for high-performance NIO-based request handling. Below are the results of a standardized load test conducted against the task-planner-app reference implementation.

Test Environment & Setup

  • Tooling: k6 v1.7.1
  • Endpoint: GET /_health (unauthenticated)
  • Profile: Graduated ramp-up from 0 to 100 Virtual Users (VUs) over 2 minutes.
  • Hardware: Local execution on Windows (Consumer-grade CPU/RAM).

Key Metrics

Metric Result
Throughput 501.12 requests/second
Median Latency (p50) 1.52 ms
p95 Latency 47.75 ms
p99 Latency 74.62 ms
Success Rate 99.84% (0.16% error rate at peak 100 VUs)

Repository Structure

.
├── nioflow-framework/
│   └── src/main/java/io/github/jhanvi857/nioflow/
│       ├── auth/            # JWT provider and auth primitives
│       ├── exception/       # Exception handlers and mapping
│       ├── middleware/      # Logger, CORS, auth, rate limit, metrics
│       ├── observability/   # Health handlers
│       ├── plugin/          # Plugin registration points
│       ├── protocol/        # Parser, request, response models
│       ├── routing/         # Route, router, groups, context
│       └── server/          # NIO accept loop and connection handlers
│
├── task-planner-app/
│   └── src/main/java/io/github/jhanvi857/taskplanner/
│       ├── controller/      # HTTP-facing handlers
│       ├── repository/      # JDBC access wrapped in futures
│       ├── db/              # Hikari and DB bootstrap
│       └── DemoApplication.java
│
├── documentation/nioflow/   # Next.js documentation portal
├── .github/workflows/       # CI build/test/security checks
├── Dockerfile               # Multi-stage image build
├── docker-compose.yml       # App + Postgres local stack
└── runbook.md               # Operational procedures

Credits & Attribution

This project is authored and maintained by Jhanvi Patel (jhanvi857).

Dependencies & Third-Party Code

  • Environment Management: Powered by dotenv-java by io.github.cdimascio. Licensed under the Apache License 2.0.
  • Networking: Core architectural patterns for the NIO engine were derived from industry-standard high-performance Java server implementations. We honor all original authors and adhere to open-source compliance.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A lightweight Java 17 HTTP micro-framework with explicit routing, middleware composition, and production-focused runtime controls.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors