tinystruct

Core Concepts

Modern Framework Philosophy

tinystruct embodies a modern approach to Java application development:

  1. No main() method required - Start applications directly with CLI commands
  2. Unified design for CLI and Web - Write once, run anywhere
  3. Built-in lightweight servers - Netty, Tomcat, or Undertow
  4. Minimal configuration - No excessive XML or YAML
  5. Performance-first architecture - Zero overhead design
  6. AI-ready - Built for AI integration with MCP support

Application Structure

AbstractApplication

The base class for all tinystruct applications. It provides:

public class MyApp extends AbstractApplication {
    @Override
    public void init() {
        // Initialize application
        System.out.println("Initializing MyApp...");
    }

    @Override
    public String version() {
        return "1.0.0";
    }
}

Actions

Actions are the core building blocks of tinystruct applications. They handle both web requests and CLI commands through a unified mechanism.

Action Annotation

@Action(
    value = "endpoint",           // URL pattern or command name
    description = "Description",  // Action description
    mode = Action.Mode.ALL       // Execution mode
)

HTTP Method-Specific Actions (New in 1.7.17)

You can now specify which HTTP methods an action responds to:

@Action(value = "users", mode = Action.Mode.HTTP_GET)
public String getUsers() {
    // Handle GET request
    return "List of users";
}

@Action(value = "users", mode = Action.Mode.HTTP_POST)
public String createUser() {
    // Handle POST request
    return "User created";
}

@Action(value = "users", mode = Action.Mode.HTTP_PUT)
public String updateUser(Integer id) {
    // Handle PUT request
    return "User updated: " + id;
}

@Action(value = "users", mode = Action.Mode.HTTP_DELETE)
public String deleteUser(Integer id) {
    // Handle DELETE request
    return "User deleted: " + id;
}

Available Action Modes

Intelligent URL Matching

@Action("users")    // Automatically matches /users, /users/123, /users/123/posts

Tinystruct automatically:

Example:

@Action("users")
public String getUser(Integer id) {
    // URL: /users/123
    // id = 123 (automatically extracted)
    return "User: " + id;
}

@Action("users")
public String getUserPosts(Integer userId, String postType) {
    // URL: /users/123/blog
    // userId = 123, postType = "blog"
    return "User " + userId + " posts of type: " + postType;
}

Configuration

Properties File

# Application settings
application.name=MyApp
application.mode=development

# Server settings
server.port=8080
server.host=localhost

# Database settings
driver=org.h2.Driver
database.url=jdbc:h2:~/test
database.user=sa
database.password=
database.connections.max=10

# HTTP configuration
default.http.max_content_length=4194304

Accessing Configuration

String appName = getConfiguration().get("application.name");
int port = Integer.parseInt(getConfiguration().get("server.port", "8080"));
boolean devMode = "development".equals(getConfiguration().get("application.mode"));

Server Options

bin/dispatcher start --import org.tinystruct.system.NettyHttpServer

Best for:

Tomcat Server

bin/dispatcher start --import org.tinystruct.system.TomcatServer

Best for:

Undertow Server

bin/dispatcher start --import org.tinystruct.system.UndertowServer

Best for:

Database Integration

Supported Databases

Basic Usage

// Using DatabaseOperator (recommended)
try (DatabaseOperator operator = new DatabaseOperator()) {
    ResultSet results = operator.query("SELECT * FROM users WHERE id = ?", id);
    // Process results
}

// Using Repository pattern
Repository repository = Type.MySQL.createRepository();
repository.connect(getConfiguration());
List<Row> results = repository.query("SELECT * FROM users");

Request Handling

Web Requests

@Action(value = "api/data", mode = Mode.HTTP_GET)
public String getData(Request request, Response response) {
    String param = request.getParameter("key");

    // Set content type
    response.headers().add(Header.CONTENT_TYPE.set("application/json"));

    // Create JSON response using Builder
    Builder builder = new Builder();
    builder.put("key", param);
    builder.put("success", true);

    return builder.toString();
}

CLI Commands

@Action(value = "generate",
        description = "Generate POJO objects",
        mode = Action.Mode.CLI)
public String generate(String tableName) {
    // Command implementation
    return "Generated POJO for table: " + tableName;
}

Event System

tinystruct includes a powerful event system for decoupled communication:

// Register event handler
EventDispatcher dispatcher = EventDispatcher.getInstance();
dispatcher.registerHandler(UserCreatedEvent.class, event -> {
    User user = event.getPayload();
    System.out.println("User created: " + user.getName());
});

// Dispatch event
dispatcher.dispatch(new UserCreatedEvent(newUser));

AI Integration

New in version 1.7.17, tinystruct includes built-in support for AI integration:

MCP (Model Context Protocol) Support

// MCP configuration in config.properties
mcp.auth.token=your_token_here

// Use MCP in your application
@Action("ai/chat")
public String chat(String message) {
    // Integration with AI models
    return aiService.processMessage(message);
}

SSE (Server-Sent Events) Support

@Action(value = "stream", mode = Mode.HTTP_GET)
public void streamData(Request request, Response response) {
    response.setHeader("Content-Type", "text/event-stream");
    response.setHeader("Cache-Control", "no-cache");
    
    // Stream data to client
    for (int i = 0; i < 10; i++) {
        response.write("data: " + i + "\n\n");
        Thread.sleep(1000);
    }
}

Security

Authentication

@Action("secure/endpoint")
public Response secureEndpoint(Request request) {
    if (!isAuthenticated(request)) {
        throw new UnauthorizedException();
    }
    // Protected code
}

Authorization

@Action("admin/users")
public Response adminOnly(Request request) {
    if (!hasRole(request, "ADMIN")) {
        throw new ForbiddenException();
    }
    // Admin-only code
}

Error Handling

try {
    // Your code
} catch (ApplicationException e) {
    logger.log(Level.SEVERE, e.getMessage(), e);
    throw new ApplicationRuntimeException(e.getMessage(), e);
}

Performance Characteristics

Next Steps