tinystruct-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesetinystruct Development Patterns
tinystruct 开发模式
Architecture and implementation patterns for building modules with the tinystruct Java framework – a lightweight, high-performance framework that treats CLI and HTTP as equal citizens, requiring no method and minimal configuration.
main()使用tinystruct Java框架构建模块的架构与实现模式——这是一个轻量、高性能的框架,将CLI和HTTP视为同等重要的交互方式,无需方法,且配置极简。
main()Core Principle
核心原则
CLI and HTTP are equal citizens. Every method annotated with should ideally be runnable from both a terminal and a web browser without modification. This "dual-mode" capability is the core design philosophy of tinystruct.
@ActionCLI与HTTP地位平等。所有标注了的方法理论上无需修改即可同时在终端和浏览器中运行。这种“双模式”能力是tinystruct的核心设计理念。
@ActionWhen to Activate
适用场景
When to Use
何时使用
- Creating new modules by extending
Application.AbstractApplication - Defining routes and command-line actions using .
@Action - Handling per-request state via .
Context - Performing JSON serialization using the native and
Buildercomponents.Builders - Working with database persistence via POJOs.
AbstractData - Generating POJOs from database tables using the command.
generate - Implementing Server-Sent Events (SSE) for real-time push.
- Handling file uploads via multipart data.
- Making outbound HTTP requests with and
URLRequest.HTTPHandler - Configuring database connections or system settings in .
application.properties - Debugging routing conflicts (Actions) or CLI argument parsing.
- 通过继承创建新的
AbstractApplication模块。Application - 使用定义路由与命令行操作。
@Action - 通过处理请求级状态。
Context - 使用原生和
Builder组件进行JSON序列化。Builders - 通过POJO实现数据库持久化。
AbstractData - 使用命令从数据库表生成POJO。
generate - 实现Server-Sent Events(SSE)进行实时推送。
- 通过multipart数据处理文件上传。
- 使用和
URLRequest发起出站HTTP请求。HTTPHandler - 在中配置数据库连接或系统设置。
application.properties - 调试路由冲突(Actions)或CLI参数解析问题。
How It Works
工作原理
The tinystruct framework treats any method annotated with as a routable endpoint for both terminal and web environments. Applications are created by extending , which provides core lifecycle hooks like and access to the request .
@ActionAbstractApplicationinit()ContextRouting is handled by the , which automatically maps path segments to method arguments and injects dependencies. For data-only services, the native and components should be used for JSON serialization to maintain a zero-dependency footprint. The database layer uses POJOs paired with XML mapping files for CRUD operations without external ORM libraries.
ActionRegistryBuilderBuildersAbstractDatatinystruct框架将所有标注了的方法视为终端和Web环境均可访问的路由端点。应用通过继承创建,该基类提供了等核心生命周期钩子,以及对请求的访问能力。
@ActionAbstractApplicationinit()Context路由由处理,它会自动将路径段映射到方法参数并注入依赖。对于纯数据服务,应使用原生和组件进行JSON序列化,以保持零依赖特性。数据库层使用 POJO搭配XML映射文件实现CRUD操作,无需外部ORM库。
ActionRegistryBuilderBuildersAbstractDataExamples
示例
Basic Application (MyService)
基础应用(MyService)
java
public class MyService extends AbstractApplication {
@Override
public void init() {
this.setTemplateRequired(false); // Disable .view lookup for data/API apps
}
@Override public String version() { return "1.0.0"; }
@Action("greet")
public String greet() {
return "Hello from tinystruct!";
}
// Path parameter: GET /?q=greet/James OR bin/dispatcher greet/James
@Action("greet")
public String greet(String name) {
return "Hello, " + name + "!";
}
}java
public class MyService extends AbstractApplication {
@Override
public void init() {
this.setTemplateRequired(false); // 禁用数据/API应用的.view文件查找
}
@Override public String version() { return "1.0.0"; }
@Action("greet")
public String greet() {
return "Hello from tinystruct!";
}
// 路径参数:GET /?q=greet/James 或 bin/dispatcher greet/James
@Action("greet")
public String greet(String name) {
return "Hello, " + name + "!";
}
}HTTP Mode Disambiguation (login)
HTTP模式区分(登录)
java
@Action(value = "login", mode = Mode.HTTP_POST)
public String doLogin(Request<?, ?> request) throws ApplicationException {
request.getSession().setAttribute("userId", "42");
return "Logged in";
}java
@Action(value = "login", mode = Mode.HTTP_POST)
public String doLogin(Request<?, ?> request) throws ApplicationException {
request.getSession().setAttribute("userId", "42");
return "Logged in";
}Native JSON Data Handling (Builder + Builders)
原生JSON数据处理(Builder + Builders)
java
import org.tinystruct.data.component.Builder;
import org.tinystruct.data.component.Builders;
@Action("api/data")
public String getData() throws ApplicationException {
Builders dataList = new Builders();
Builder item = new Builder();
item.put("id", 1);
item.put("name", "James");
dataList.add(item);
Builder response = new Builder();
response.put("status", "success");
response.put("data", dataList);
return response.toString(); // {"status":"success","data":[{"id":1,"name":"James"}]}
}java
import org.tinystruct.data.component.Builder;
import org.tinystruct.data.component.Builders;
@Action("api/data")
public String getData() throws ApplicationException {
Builders dataList = new Builders();
Builder item = new Builder();
item.put("id", 1);
item.put("name", "James");
dataList.add(item);
Builder response = new Builder();
response.put("status", "success");
response.put("data", dataList);
return response.toString(); // {"status":"success","data":[{"id":1,"name":"James"}]}
}SSE (Server-Sent Events)
SSE(Server-Sent Events)
java
import org.tinystruct.http.SSEPushManager;
@Action("sse/connect")
public String connect() {
return "{\"type\":\"connect\",\"message\":\"Connected to SSE\"}";
}
// Push to a specific client
String sessionId = getContext().getId();
Builder msg = new Builder();
msg.put("text", "Hello, user!");
SSEPushManager.getInstance().push(sessionId, msg);
// Broadcast to all
// Broadcast to all
SSEPushManager.getInstance().broadcast(msg);java
import org.tinystruct.http.SSEPushManager;
@Action("sse/connect")
public String connect() {
return "{\"type\":\"connect\",\"message\":\"Connected to SSE\"}";
}
// 推送给指定客户端
String sessionId = getContext().getId();
Builder msg = new Builder();
msg.put("text", "Hello, user!");
SSEPushManager.getInstance().push(sessionId, msg);
// 广播给所有客户端
SSEPushManager.getInstance().broadcast(msg);File Upload
文件上传
java
import org.tinystruct.data.FileEntity;
@Action(value = "upload", mode = Mode.HTTP_POST)
public String upload(Request<?, ?> request) throws ApplicationException {
List<FileEntity> files = request.getAttachments();
if (files != null) {
for (FileEntity file : files) {
System.out.println("Uploaded: " + file.getFilename());
}
}
return "Upload OK";
}java
import org.tinystruct.data.FileEntity;
@Action(value = "upload", mode = Mode.HTTP_POST)
public String upload(Request<?, ?> request) throws ApplicationException {
List<FileEntity> files = request.getAttachments();
if (files != null) {
for (FileEntity file : files) {
System.out.println("Uploaded: " + file.getFilename());
}
}
return "Upload OK";
}Configuration
配置
Settings are managed in .
src/main/resources/application.propertiesproperties
undefined设置项在中管理。
src/main/resources/application.propertiesproperties
undefinedDatabase
数据库
driver=org.h2.Driver
database.url=jdbc:h2:~/mydb
database.user=sa
database.password=
driver=org.h2.Driver
database.url=jdbc:h2:~/mydb
database.user=sa
database.password=
Server
服务器
default.home.page=hello
server.port=8080
default.home.page=hello
server.port=8080
Locale
区域设置
default.language=en_US
default.language=en_US
Session (Redis for clustered environments)
会话(集群环境使用Redis)
default.session.repository=org.tinystruct.http.RedisSessionRepository
default.session.repository=org.tinystruct.http.RedisSessionRepository
redis.host=127.0.0.1
redis.host=127.0.0.1
redis.port=6379
redis.port=6379
Access config values in your application:
```java
String port = this.getConfiguration("server.port");
在应用中访问配置值:
```java
String port = this.getConfiguration("server.port");Red Flags & Anti-patterns
常见问题与反模式
| Symptom | Correct Pattern |
|---|---|
Importing | Use |
Using | Use |
| Call |
Annotating | Actions must be |
Hardcoding | Use |
Manual | Prefer the |
| Action not found at runtime | Ensure class is imported via |
| CLI arg not visible | Pass with |
| Two methods same path, wrong one fires | Set explicit |
| 问题表现 | 正确做法 |
|---|---|
导入 | 使用 |
使用 | 使用 |
出现 | 在 |
给 | Action方法必须为 |
在应用中硬编码 | 使用 |
手动注册 | 优先使用 |
| 运行时提示Action未找到 | 确保类通过 |
| CLI参数不可见 | 使用 |
| 两个方法路径相同,触发错误的方法 | 设置明确的 |
Best Practices
最佳实践
- Granular Applications: Break logic into smaller, focused applications rather than one monolithic class.
- Setup in : Leverage
init()for setup (config, DB) rather than the constructor. Do NOT callinit()— usesetAction()annotation.@Action - Mode Awareness: Use the parameter in
Modeto restrict sensitive operations to@Actiononly or specific HTTP methods.CLI - Context over Params: For optional CLI flags, use rather than adding parameters to the method signature.
getContext().getAttribute("--flag") - Asynchronous Events: For heavy tasks triggered by events, use inside the event handler.
CompletableFuture.runAsync()
- 细粒度应用:将逻辑拆分为更小、专注的应用,而非单一的巨型类。
- 在中初始化:利用
init()进行配置、数据库等初始化操作,而非构造函数。请勿调用init()——使用setAction()注解。@Action - 模式感知:在中使用
@Action参数将敏感操作限制为仅Mode模式或特定HTTP方法。CLI - 优先使用Context而非参数:对于可选CLI标志,使用而非在方法签名中添加参数。
getContext().getAttribute("--flag") - 异步事件处理:对于事件触发的重型任务,在事件处理器内部使用。
CompletableFuture.runAsync()
Technical Reference
技术参考
Detailed guides are available in the directory:
references/- Architecture & Config — Abstractions, Package Map, Properties
- Routing & @Action — Annotation details, Modes, Parameters
- Data Handling — Builder, Builders, JSON serialization & parsing
- Database Persistence — AbstractData POJOs, CRUD, mapping XML, POJO generation
- System & Usage — Context, Sessions, SSE, File Uploads, Events, Networking
- Testing Patterns — JUnit 5 unit and HTTP integration testing
详细指南位于目录中:
references/- 架构与配置 — 抽象层、包结构、配置属性
- 路由与@Action — 注解细节、模式、参数
- 数据处理 — Builder、Builders、JSON序列化与解析
- 数据库持久化 — AbstractData POJO、CRUD、映射XML、POJO生成
- 系统与使用 — Context、会话、SSE、文件上传、事件、网络
- 测试模式 — JUnit 5单元测试与HTTP集成测试
Reference Source Files (Internal)
参考源文件(内部)
- — Core base class with lifecycle hooks
src/main/java/org/tinystruct/AbstractApplication.java - — Annotation & Modes
src/main/java/org/tinystruct/system/annotation/Action.java - — Routing Engine
src/main/java/org/tinystruct/application/ActionRegistry.java - — JSON object serializer
src/main/java/org/tinystruct/data/component/Builder.java - — JSON array serializer
src/main/java/org/tinystruct/data/component/Builders.java - — Base POJO class with CRUD
src/main/java/org/tinystruct/data/component/AbstractData.java - — Mapping XML parser
src/main/java/org/tinystruct/data/Mapping.java - — POJO generator reference
src/main/java/org/tinystruct/data/tools/MySQLGenerator.java - — SQL-to-Java type mappings
src/main/java/org/tinystruct/data/component/FieldType.java - — Fluent SQL query builder
src/main/java/org/tinystruct/data/component/Condition.java - — SSE connection management
src/main/java/org/tinystruct/http/SSEPushManager.java - — Registry test examples
src/test/java/org/tinystruct/application/ActionRegistryTest.java - — HTTP integration test patterns
src/test/java/org/tinystruct/system/HttpServerHttpModeTest.java
- — 包含生命周期钩子的核心基类
src/main/java/org/tinystruct/AbstractApplication.java - — 注解与模式定义
src/main/java/org/tinystruct/system/annotation/Action.java - — 路由引擎
src/main/java/org/tinystruct/application/ActionRegistry.java - — JSON对象序列化器
src/main/java/org/tinystruct/data/component/Builder.java - — JSON数组序列化器
src/main/java/org/tinystruct/data/component/Builders.java - — 带CRUD功能的POJO基类
src/main/java/org/tinystruct/data/component/AbstractData.java - — XML映射解析器
src/main/java/org/tinystruct/data/Mapping.java - — POJO生成器参考实现
src/main/java/org/tinystruct/data/tools/MySQLGenerator.java - — SQL到Java类型映射
src/main/java/org/tinystruct/data/component/FieldType.java - — 流式SQL查询构建器
src/main/java/org/tinystruct/data/component/Condition.java - — SSE连接管理器
src/main/java/org/tinystruct/http/SSEPushManager.java - — 注册器测试示例
src/test/java/org/tinystruct/application/ActionRegistryTest.java - — HTTP集成测试模式
src/test/java/org/tinystruct/system/HttpServerHttpModeTest.java