All skills

Use this skill to build or fix tinystruct app modules and small services. Covers routes, Context, Builder JSON, settings, tests, and actions that work in both CLI and HTTP modes.

Use this Skill: https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill

This session only. Nothing lands on disk.

SKILL.md

≈46 tokens always: the name and description. ≈2k when used: this file.

tinystruct Development Patterns

Credit

This skill comes from ECC. Credit ECC in any copy or changed version.

Use This Skill When

Use this skill when you:

  • Create a module that extends AbstractApplication.
  • Add a CLI or HTTP action with @Action.
  • Read request data from Context.
  • Return JSON data with Builder.
  • Change application.properties.
  • Create or rebuild bin/dispatcher.
  • Fix route clashes or CLI argument errors.

Main Rules

  1. Extend AbstractApplication.
  2. Put @Action only on public methods.
  3. Use one action pattern for both CLI and HTTP when they do the same job.
  4. Set the HTTP mode when an action must use a set method, such as POST.
  5. Use Builder for JSON data.
  6. Use Context only for data tied to the current request.
  7. Turn off views for an API-only app.
  8. Use bin/dispatcher as the main CLI entry point.
  9. Let tinystruct find actions. Do not add them to ActionRegistry by hand.
  10. Test both valid and bad input.

Build Steps

1. Create the app

public class MyService extends AbstractApplication {
    @Override
    public void init() {
        setTemplateRequired(false);
    }

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

Call setTemplateRequired(false) when the app returns data and has no .view files.

2. Add a simple action

@Action("greet")
public String greet() {
    return "Hello from tinystruct!";
}

Run it from the CLI:

bin/dispatcher greet

The same action can be used as an HTTP route when the app runs as a web service.

3. Add route values

Each regex capture group must match one method argument. Keep the same order.

@Action("api/user/(\\d+)")
public String getUser(int userId) {
    return "User ID: " + userId;
}

Examples:

HTTP: /api/user/123
CLI:  bin/dispatcher api/user/123

Use a narrow pattern. For an ID, prefer (\\d+) over (.*).

4. Set the HTTP method

Use an HTTP mode when a route must accept only one method.

@Action(value = "login", mode = Mode.HTTP_POST)
public boolean login() {
    return true;
}

Do not put secret data in a URL. Read passwords and tokens from the request body or request context.

5. Return JSON data

Use tinystruct's Builder. Do not add Gson or Jackson just for basic JSON.

@Action("api/data")
public Builder getData() throws ApplicationException {
    Builder result = new Builder();
    result.put("status", "success");

    Builder user = new Builder();
    user.put("id", 1);
    user.put("name", "James");

    result.put("data", user);
    return result;
}

Keep one clear shape for both success and error data. Do not return a Builder on success and a plain string on failure.

6. Use request context with care

Use Context for request values, session values, and other request state.

  • Check that a value exists before using it.
  • Check its type before casting it.
  • Do not store request state in static fields.
  • Do not reuse one request's data in another request.
  • Handle missing or bad values with a clear error result.

See System and Usage for the exact Context calls.

7. Set app options

Put settings in:

src/main/resources/application.properties

Use the exact property names listed in Architecture and Settings.

Do not commit passwords, keys, or tokens. Read them from the safe setting source used by the project.

8. Create the dispatcher

Use ApplicationManager.init() when the project needs a new or rebuilt bin/dispatcher.

Before replacing an existing script:

  • Check whether it has local changes.
  • Keep its run rights.
  • Run one known action after it is built.

Do not add a separate main(String[] args) to each module.

Full Usage Example

This service supports one route in both CLI and HTTP modes.

public class UserService extends AbstractApplication {
    @Override
    public void init() {
        setTemplateRequired(false);
    }

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

    @Action("api/user/(\\d+)")
    public Builder getUser(int userId) throws ApplicationException {
        Builder result = new Builder();
        result.put("status", "success");

        Builder user = new Builder();
        user.put("id", userId);
        user.put("name", "James");

        result.put("data", user);
        return result;
    }
}

Run it:

bin/dispatcher api/user/123

Test these cases:

api/user/123     should match
api/user/0       should match if zero is allowed
api/user/abc     should not match
api/user/        should not match

Also call the HTTP route and check that it returns the same data shape.

Edge Cases

Route clashes

Two actions may match the same path.

  • Search all @Action values.
  • Make each pattern as narrow as possible.
  • Check fixed routes before adding broad regex routes.
  • Test the path in both CLI and HTTP modes.

Route value errors

A route may match text that the method cannot read.

  • Match digits for an int.
  • Keep capture groups and method arguments in the same order.
  • Do not add a capture group unless the method accepts it.
  • Test very large numbers and missing values.

Wrong HTTP method

A route may exist but reject the request method.

  • Check the action's mode.
  • Use Mode.HTTP_POST for POST-only work.
  • Do not let a state-changing action run through GET unless the app calls for it.

Missing views

If an API-only app throws FileNotFoundException for a .view file, call:

setTemplateRequired(false);

Do this in init().

Bad or missing settings

  • Give clear errors for required settings.
  • Do not hide a missing setting with an unsafe default.
  • Keep local and test settings apart when the project supports it.
  • Do not print secret values in logs or errors.

JSON values

  • Pick one rule for missing values, such as null or no field.
  • Keep number, text, and boolean types stable.
  • Use nested Builder values for nested objects.
  • Check Data Handling before adding lists or custom types.

Tests

Use JUnit 5.

Test that:

  • The app starts.
  • Each action is in ActionRegistry.
  • Valid paths reach the right action.
  • Bad paths do not match.
  • Capture groups map to the right argument types.
  • HTTP method limits work.
  • CLI and HTTP calls give the same result shape.
  • API-only apps do not look for view files.
  • Missing context and settings fail in a clear way.

Do not rely only on direct method tests. A direct call will not catch a bad @Action pattern.

Common Problems

Problem Fix
Gson or Jackson was added for basic JSON Use org.tinystruct.data.component.Builder.
A .view file is missing Call setTemplateRequired(false) in init().
An action is not found Make the method public and check its @Action value.
A route value cannot become an int Use a digit-only capture group and test its range.
Two actions match one path Make the patterns more exact.
CLI and HTTP give different results Put shared work in one method and keep input rules the same.
Each module has its own main method Use bin/dispatcher.
Code adds actions to ActionRegistry by hand Use @Action and automatic discovery.
Request data is stored in a static field Keep it in Context or a local value.

Reference Files

Read only the file needed for the task:

Source: SKILL.md on GitHub

No third-party reports yet.

Signed by skilld at c43daec. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated last week
origin
ECC

README badge

README badge for agenticluke/tinystruct-builder-plus