Skip to content

Quarklets is a web framework built on Quarkus, with explicit servlet support via Undertow and dependency management through Arc. It is designed for RESTful APIs, handling JSON input and output, and prioritizes transparency in servlet operations while enabling modern web service development.

License

Notifications You must be signed in to change notification settings

anamitraupadhyay/Quarklets

Repository files navigation

quarkletslogo

Thread-Runnable Pattern Implementation for JSON Binding

Overview

This implementation demonstrates how the ServletJsonProcessor orchestrates the complete 4-step JSON processing pipeline using the Thread-Runnable pattern, reducing complex multi-step operations to a single elegant method call.

The Problem Solved

Before (Manual 4-Step Process):

// Step 1: HttpServletRequest → StringBuilder
StringBuilder jsonData = DataHandlerFromServlet.stringbuilderparse(request);

// Step 2: Find JSON start position
int jsonStart = DataHandlerFromServlet.findJsonStart(jsonData);

// Step 3: StringBuilder → Tokens  
Tokenizer tokenizer = new Tokenizer();
List<Token> tokens = tokenizer.JsonParse(jsonData, jsonStart);

// Step 4: Tokens → Dino objects
SimpleParser parser = new SimpleParser();
Dino jsonTree = parser.parse(tokens);

// Step 5: Create POJO instance
TransactionData transaction = new TransactionData();

// Step 6: Bind data
transaction.bind(jsonTree);

After (Thread-Runnable Pattern):

// Single elegant line - all steps handled internally
TransactionData result = ServletJsonProcessor.bind(request, TransactionData.class);

Thread-Runnable Pattern Analogy

Traditional Thread-Runnable:

Thread thread = new Thread(() -> { /* work implementation */ });
thread.start(); // Executes the work

Our JSON Binding Pattern:

TransactionData result = ServletJsonProcessor.bind(request, TransactionData.class);
// HttpServletRequest = Thread (has work to do)
// TransactionData = Runnable (implements work via bind method)
// ServletJsonProcessor = Orchestrator (executes the binding)

Key Components

1. ServletJsonProcessor (Orchestrator)

  • Purpose: Single class that orchestrates the entire 4-step pipeline
  • Usage: ServletJsonProcessor.bind(request, TargetClass.class)
  • Benefits:
    • ✅ One method call instead of 6+ manual steps
    • ✅ Type-safe generic binding
    • ✅ Automatic error handling
    • ✅ No changes required to existing parsing infrastructure

2. AutobindInterface (Runnable equivalent)

  • Purpose: POJOs implement this to define their binding behavior
  • Method: void bind(Dino jsonTree) - like Runnable.run()
  • Benefits:
    • ✅ Automatic field extraction using helper methods
    • ✅ Type conversion (getInt, getDouble, getString)
    • ✅ Consistent binding pattern across all POJOs

3. Existing Infrastructure (Unchanged)

  • DataHandlerFromServlet: HttpServletRequest → StringBuilder
  • Tokenizer: StringBuilder → List
  • SimpleParser: Tokens → Dino object tree
  • Dino classes: JSON structure representation

Usage Examples

Basic Usage

@WebServlet("/api/transaction")
public class TransactionServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        // Single line - HttpServletRequest becomes bound POJO
        TransactionData data = ServletJsonProcessor.bind(request, TransactionData.class);
        
        // Object is ready for business logic
        processTransaction(data);
    }
}

With Logging (For Learning/Debugging)

TransactionData result = ServletJsonProcessor.bindWithLogging(
    request, 
    TransactionData.class, 
    true  // Enable step-by-step logging
);

Constructor-Based Usage

ServletJsonProcessor<TransactionData> processor = 
    new ServletJsonProcessor<>(request, TransactionData.class);
TransactionData result = processor.process();

Implementation Benefits

Minimal Changes Required

  • Zero changes to existing parsing infrastructure
  • Zero changes to existing Dino classes
  • Zero changes to existing POJO binding logic
  • Only addition: New orchestrator class

Clean Code

  • From: 12+ method calls with manual orchestration
  • To: 1 method call with automatic orchestration
  • Pattern: Familiar Thread-Runnable approach
  • Maintenance: Single point of control

Type Safety

  • Generic: Works with any class implementing AutobindInterface
  • Compile-time: Type checking for target classes
  • Runtime: Automatic instantiation and binding

Running the Demo

# Compile and run the demonstration
./gradlew compileJava
java -cp lib/build/classes/java/main io.github.anamitraupadhyay.Quarklets.experimetal.exampleofrunnablelikeandsimpleflowlike.ThreadRunnablePatternDemo

Test Coverage

# Run all tests including ServletJsonProcessor tests
./gradlew test

Test Results:

  • ✅ Single-step binding with complete JSON
  • ✅ Constructor-based approach
  • ✅ Partial JSON handling (missing fields)
  • ✅ Type conversion accuracy
  • ✅ Thread-Runnable pattern validation

Summary

The ServletJsonProcessor successfully implements the Thread-Runnable pattern for JSON binding:

  1. Elegance: Reduces complex multi-step process to single method call
  2. Minimal Changes: Uses existing infrastructure without modifications
  3. Learning-Oriented: Clear analogy with familiar Thread-Runnable pattern
  4. Production-Ready: Complete error handling and type safety
  5. Extensible: Generic design works with any AutobindInterface implementation

About

Quarklets is a web framework built on Quarkus, with explicit servlet support via Undertow and dependency management through Arc. It is designed for RESTful APIs, handling JSON input and output, and prioritizes transparency in servlet operations while enabling modern web service development.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages