Communitygithub.com

tinystruct-패턴

tinystruct Java 프레임워크 개발을 위한 전문 가이드입니다. tinystruct 코드베이스나 이 프레임워크를 사용하는 모든 프로젝트에서 Application 클래스 생성, @Action 매핑 라우트, 단위 테스트, ActionRegistry, HTTP/CLI 듀얼 모드 처리, 내장 HTTP 서버, 이벤트 시스템, Builder/Builders를 사용한 JSON, AbstractData를 통한 데이터베이스 영속성, POJO 생성, 서버-전송 이벤트(SSE), 파일 업로드, 아웃바운드 HTTP 네트워킹 등을 다룰 때 활성화하세요.

tinystruct-패턴란 무엇인가요?

이 스킬은 tinystruct Java 프레임워크를 사용하여 애플리케이션을 개발하고 유지보수하는 개발자를 위한 포괄적인 안내서 역할을 합니다. tinystruct는 CLI와 HTTP를 동등한 시민으로 취급하는 경량 고성능 프레임워크로, `main()` 메서드가 필요하지 않으며 최소한의 설정만으로 작동합니다. 스킬은 `@Action` 어노테이션을 통한 듀얼 모드 라우팅, `Builder`/`Builders`를 이용한 네이티브 JSON 직렬화, `AbstractData` POJO와 XML 매핑 파일을 통한 데이터베이스 CRUD, 서버-전송 이벤트(SSE)를 통한 실시간 푸시, MCP(Model Context Protocol) 서버 및 도구 통합, 파일 업로드, 아웃바운드 HTTP 요청 등 핵심 패턴을 다룹니다. 또한 일반적인 안티패턴과 권장사항을 표 형식으로 제시하며, JUnit 5 단위 테스트 및 HTTP 통합 테스트 패턴도 포함되어 있어 tinystruct 기반 프로젝트의 효과적인 개발과 디버깅을 지원합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/tinystruct-patterns

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

tinystruct 개발 패턴

tinystruct Java 프레임워크로 모듈을 구축하기 위한 아키텍처 및 구현 패턴입니다. tinystruct는 CLI와 HTTP를 동등하게 취급하며, main() 메서드가 필요 없고 최소한의 설정만으로 동작하는 경량 고성능 프레임워크입니다.

핵심 원칙

CLI와 HTTP는 동등한 시민입니다. @Action으로 어노테이션된 모든 메서드는 수정 없이 터미널과 웹 브라우저 모두에서 실행 가능해야 합니다. 이러한 "듀얼 모드" 기능이 tinystruct의 핵심 설계 철학입니다.

활성화 시점

사용해야 할 때

  • AbstractApplication을 확장하여 새로운 Application 모듈을 생성할 때.
  • @Action을 사용하여 라우트와 커맨드라인 액션을 정의할 때.
  • Context를 통해 요청별 상태를 처리할 때.
  • 네이티브 Builder 및 Builders 컴포넌트를 사용하여 JSON 직렬화를 수행할 때.
  • AbstractData POJO를 통해 데이터베이스 영속성을 작업할 때.
  • generate 명령을 사용하여 데이터베이스 테이블에서 POJO를 생성할 때.
  • 실시간 푸시를 위해 서버-전송 이벤트(SSE)를 구현할 때.
  • 멀티파트 데이터를 통해 파일 업로드를 처리할 때.
  • URLRequest 및 HTTPHandler를 사용하여 아웃바운드 HTTP 요청을 만들 때.
  • application.properties에서 데이터베이스 연결 또는 시스템 설정을 구성할 때.
  • 라우팅 충돌(Actions) 또는 CLI 인수 파싱을 디버깅할 때.

작동 방식

tinystruct 프레임워크는 @Action으로 어노테이션된 모든 메서드를 터미널과 웹 환경 모두에서 라우팅 가능한 엔드포인트로 취급합니다. 애플리케이션은 init()과 같은 핵심 생명주기 훅과 요청 Context에 대한 접근을 제공하는 AbstractApplication을 확장하여 생성됩니다.

라우팅은 ActionRegistry에 의해 처리되며, 경로 세그먼트를 메서드 인수에 자동으로 매핑하고 의존성을 주입합니다. 데이터 전용 서비스의 경우, 네이티브 Builder 및 Builders 컴포넌트를 JSON 직렬화에 사용하여 의존성 제로 풋프린트를 유지해야 합니다. 데이터베이스 계층은 외부 ORM 라이브러리 없이 CRUD 연산을 위해 XML 매핑 파일과 쌍을 이루는 AbstractData POJO를 사용합니다.

예제

기본 애플리케이션 (MyService)

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 모드 구분 (login)

@Action(value = "login", mode = Mode.HTTP_POST)
public String doLogin(Request<?, ?> request) throws ApplicationException {
    request.getSession().setAttribute("userId", "42");
    return "Logged in";
}

네이티브 JSON 데이터 처리 (Builder + Builders)

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 (서버-전송 이벤트)

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);

파일 업로드

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";
}

MCP 서버 및 도구 통합

tinystruct는 SDK 버전 **1.7.26**부터 Model Context Protocol (MCP)을 기본 지원합니다. MCP API (예: org.tinystruct.mcp.MCPTool, org.tinystruct.mcp.MCPServer, org.tinystruct.mcp.MCPException)는 코어 의존성에 직접 포함되어 있습니다:

<dependency>
    <groupId>org.tinystruct</groupId>
    <artifactId>tinystruct</artifactId>
    <version>1.7.26</version>
</dependency>

보안 경고 (프롬프트 인젝션): 도구 반환 값은 AI 모델의 컨텍스트 윈도우에 직접 공급됩니다. 도구의 반환 문자열에 포함시키기 전에 호출자가 제공한 모든 인수를 반드시 검증하고 삭제해야 합니다. 입력을 살균하지 않으면 공격자가 모델의 동작을 재정의하는 적대적 명령(프롬프트 인젝션)을 주입할 수 있습니다. 항상 길이, 문자 집합 및 null 여부를 검증하세요.

MCP 도구를 생성하려면:

  1. org.tinystruct.mcp.MCPTool을 확장합니다.
  2. @Action으로 연산을 어노테이션하고 arguments 배열 내에서 @Argument를 사용하여 매개변수를 선언합니다.
  3. @Argument의 키와 일치하는 명시적 메서드 인수로 매개변수를 받습니다. (도구 인수에 getContext().getAttribute(...)를 사용하지 마십시오).
import org.tinystruct.mcp.MCPTool;
import org.tinystruct.mcp.MCPException;
import org.tinystruct.system.annotation.Action;
import org.tinystruct.system.annotation.Argument;

public class MyCustomTool extends MCPTool {
    public MyCustomTool() {
        super("custom", "A custom tool for demonstrating MCP");
    }

    @Action(
        value = "custom/hello",
        description = "Say hello to someone",
        arguments = {
            @Argument(key = "name", description = "The name to greet", type = "string", optional = false)
        }
    )
    public String hello(String name) throws MCPException {
        // 보안: 프롬프트 인젝션 취약점을 방지하기 위해
        // 모델에 반환하기 전에 도구 입력을 검증/삭제합니다.
        if (name == null || name.length() > 50 || !name.matches("^[a-zA-Z0-9 ]+$")) {
            throw new MCPException("Invalid name provided");
        }
        return "Hello, " + name + "!";
    }
}

MCP 서버를 배포하려면:

  1. org.tinystruct.mcp.MCPServer를 확장합니다.
  2. init()을 재정의하고 this.registerTool()을 사용하여 도구를 등록합니다. 프레임워크가 자동으로 @Action 메서드를 스캔하고 매핑합니다.
import org.tinystruct.mcp.MCPServer;

public class MyMCPServer extends MCPServer {
    @Override
    public void init() {
        super.init();
        this.registerTool(new MyCustomTool());
    }

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

디스패처를 통해 서버를 실행합니다:

bin/dispatcher start --import org.tinystruct.system.HttpServer --import com.example.MyMCPServer

설정

설정은 src/main/resources/application.properties에서 관리됩니다.

# Database
driver=org.h2.Driver
database.url=jdbc:h2:~/mydb
database.user=sa
database.password=

# Server
default.home.page=hello
server.port=8080

# Locale
default.language=en_US

# Session (Redis for clustered environments)
# default.session.repository=org.tinystruct.http.RedisSessionRepository
# redis.host=127.0.0.1
# redis.port=6379

애플리케이션에서 설정 값에 접근:

String port = this.getConfiguration("server.port");

위험 신호 및 안티패턴

증상올바른 패턴
com.google.gson 또는 com.fasterxml.jackson 임포트org.tinystruct.data.component.Builder / Builders 사용
JSON 배열에 List<Builder> 사용제네릭 타입 소거 문제를 피하기 위해 Builders 사용
ApplicationRuntimeException: template not foundAPI 전용 앱의 경우 init()에서 setTemplateRequired(false) 호출
@Action으로 private 메서드 어노테이션액션은 프레임워크에 등록되려면 public이어야 함
앱에서 main(String[] args) 하드코딩모든 모듈의 진입점으로 bin/dispatcher 사용
수동 ActionRegistry 등록자동 발견을 위해 @Action 어노테이션 선호
런타임에 액션을 찾을 수 없음클래스가 --import로 임포트되었거나 application.properties에 나열되었는지 확인
CLI 인수가 보이지 않음--key value로 전달; getContext().getAttribute("--key")로 접근
동일 경로의 두 메서드 중 잘못된 것이 실행됨명확한 mode 설정 (예: HTTP_GET vs HTTP_POST)으로 구분

모범 사례

  1. 세분화된 애플리케이션: 하나의 모놀리식 클래스보다는 작고 집중된 애플리케이션으로 로직을 분할하세요.
  2. init()에서 설정: 생성자보다는 init()을 설정(구성, DB)에 활용하세요. setAction()을 호출하지 말고 @Action 어노테이션을 사용하세요.
  3. 모드 인식: @Action의 Mode 매개변수를 사용하여 민감한 연산을 CLI 전용 또는 특정 HTTP 메서드로 제한하세요.
  4. 매개변수보다 Context: 선택적 CLI 플래그의 경우 메서드 시그니처에 매개변수를 추가하는 대신 getContext().getAttribute("--flag")를 사용하세요.
  5. 비동기 이벤트: 이벤트에 의해 트리거되는 무거운 작업의 경우 이벤트 핸들러 내에서 CompletableFuture.runAsync()를 사용하세요.

기술 참조

자세한 가이드는 references/ 디렉토리에서 확인할 수 있습니다:

참조 소스 파일 (내부)

  • src/main/java/org/tinystruct/AbstractApplication.java — 생명주기 훅을 포함한 핵심 기본 클래스
  • src/main/java/org/tinystruct/system/annotation/Action.java — 어노테이션 및 모드
  • src/main/java/org/tinystruct/application/ActionRegistry.java — 라우팅 엔진
  • src/main/java/org/tinystruct/data/component/Builder.java — JSON 객체 직렬화기
  • src/main/java/org/tinystruct/data/component/Builders.java — JSON 배열 직렬화기
  • src/main/java/org/tinystruct/data/component/AbstractData.java — CRUD를 포함한 기본 POJO 클래스
  • src/main/java/org/tinystruct/data/Mapping.java — 매핑 XML 파서
  • src/main/java/org/tinystruct/data/tools/MySQLGenerator.java — POJO 생성기 참조
  • src/main/java/org/tinystruct/data/component/FieldType.java — SQL-to-Java 타입 매핑
  • src/main/java/org/tinystruct/data/component/Condition.java — 플루언트 SQL 쿼리 빌더
  • src/main/java/org/tinystruct/http/SSEPushManager.java — SSE 연결 관리
  • src/test/java/org/tinystruct/application/ActionRegistryTest.java — 레지스트리 테스트 예제
  • src/test/java/org/tinystruct/system/HttpServerHttpModeTest.java — HTTP 통합 테스트 패턴

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

관련 스킬