Skip to content

patton174/coco-framework

Coco Framework

A high-convention Spring Boot Web server framework for fast, production-ready Java services.

English · 简体中文

Java 17+ Spring Boot 4.1 Maven 3.8.9 Apache 2.0

Install · Capabilities · SQL Guard · Boundary · Extension Boundaries · Samples · Stars · Contributors


Overview

Coco Framework helps teams build Spring Boot Web servers with a strong black-box infrastructure foundation and a normal Java/Spring business programming model.

The framework is designed for SaaS systems, internal services, admin APIs, integration servers, and general Web applications. It is not a zero-code business runtime and does not force one user, role, menu, organization, or tenant model onto every project.

Infrastructure defaults are automatic. Business code is explicit, generated, or user-owned.

Install

Use coco-parent as the application parent and add the single starter dependency.

<parent>
    <groupId>io.github.patton174</groupId>
    <artifactId>coco-parent</artifactId>
    <version>${coco.version}</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>io.github.patton174</groupId>
        <artifactId>coco-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

Optional feature selection remains declarative:

coco:
  features:
    disabled:
      - mybatis-plus
      - tenant
      - data-permission

Or Java-based:

@CocoFeatures(disabled = {
        CocoFeature.TENANT,
        CocoFeature.DATA_PERMISSION
})
@Configuration(proxyBeanMethods = false)
class ApplicationCocoConfiguration {
}

Prefer YAML or @CocoFeatures for feature selection. The older CocoConfigurer Java hook is kept for compatibility but is deprecated.

Business controllers remain ordinary Spring code:

@RestController
@RequestMapping("/orders")
class OrderController {

    private final OrderService orderService;

    OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping
    OrderResponse create(@RequestBody CreateOrderRequest request) {
        return this.orderService.create(request);
    }
}

Explicit CRUD Source Generation

When a project needs standard CRUD scaffolding, add coco-codegen.yml at its root:

base-package: com.example.catalog
resources:
  - name: Product
    table: catalog_product
    api-path: /products
    id: { name: id, column: id, type: Long, strategy: AUTO }
    fields:
      - { name: sku, column: sku, type: String, required: true }
      - { name: unitPrice, column: unit_price, type: BigDecimal, required: true }

Run the opt-in goal:

mvn coco:generate

The generator writes to src/main/java by default and refuses to overwrite existing files. It produces ordinary Controller, DTO, application-service, domain-repository, and MyBatis-Plus infrastructure source owned by the business project. The goal is not bound to the build lifecycle and never exposes entities automatically at runtime.

Production SQL Guard

Coco keeps MyBatis-Plus SQL guard disabled by default so first adoption does not break existing maintenance SQL. For production services, replay or review application SQL first, then enable the guard explicitly:

coco:
  mybatis-plus:
    sql-guard:
      block-attack-enabled: true
      illegal-sql-enabled: true

When enabled, MyBatis-Plus may reject legitimate SQL that should be rewritten, reviewed, or explicitly ignored only for controlled maintenance statements:

  • UPDATE or DELETE without a selective WHERE, or with tautological conditions such as 1 = 1.
  • SELECT, UPDATE, or DELETE without WHERE when IllegalSQLInnerInterceptor is enabled.
  • predicates using OR, !=, functions on the checked column side, or parser-detected subquery patterns.
  • predicates or join conditions whose first checked column is not covered by index metadata.
  • complex join, schema-qualified, vendor-specific, or dynamically generated SQL that the JSQLParser-based guard cannot validate reliably.

Cluster Replay Protection

The default InMemoryCocoReplayStore is intentionally process-local. It is suitable for one application instance and local development, but clustered services must use a shared store. When the application already provides Spring JdbcOperations, select the built-in JDBC reference implementation explicitly:

coco:
  web:
    replay:
      store-type: jdbc
      jdbc:
        table-name: coco_replay_key

Coco does not execute database migrations. Create the equivalent structure through the application's existing migration process, adapting this baseline DDL to the selected database:

CREATE TABLE coco_replay_key (
    replay_key_hash VARCHAR(64) NOT NULL,
    expires_at_epoch_millis BIGINT NOT NULL,
    PRIMARY KEY (replay_key_hash)
);
CREATE INDEX idx_coco_replay_key_expires_at
    ON coco_replay_key (expires_at_epoch_millis);

The unique key provides cross-instance atomic reservation, while Coco stores only a SHA-256 digest and cleans expired rows in the background. Reservation-path database failures fail protected requests closed; asynchronous cleanup failures are logged and retried. The Servlet filter reserves before normal Controller transaction boundaries. Schema lifecycle, database availability, clock synchronization, direct-call transaction use, and exactly-once side effects remain application responsibilities. With multiple JdbcOperations Beans, mark the intended candidate @Primary or provide a custom CocoReplayStore, which still replaces both built-in stores.

Async Logging Backpressure

Coco logging uses a bounded asynchronous queue by default. ERROR records and records carrying an exception are always written synchronously; when the queue is full, WARN also falls back to synchronous output. Rejected TRACE, DEBUG, and INFO records remain intentionally droppable so queue submission never waits for capacity.

Every actual drop increments an in-process counter, while each non-reentrant drop notifies CocoAsyncLogDropListener. The default listener writes a direct SLF4J warning for the first drop and then at power-of-two totals, providing a low-noise overload signal without feeding diagnostics back into the full Coco queue. Applications can replace it with one Bean:

@Bean
CocoAsyncLogDropListener cocoAsyncLogDropListener(MeterRegistry registry) {
    Counter counter = registry.counter("coco.logging.async.dropped");
    return (level, handleName, totalDropped) -> counter.increment();
}

The callback receives only the level, log handle name, and cumulative count; message text and exceptions are not exposed. It runs on the submitting thread and must remain fast and avoid blocking. Concurrent callbacks receive unique cumulative values but are not ordered across threads; listener re-entry is suppressed while nested drops are still counted. This mechanism is overload observability, not durable log delivery; applications requiring delivery guarantees should provide their own CocoLogSink or audit recorder.

What Coco Provides

Web

Web Runtime
Unified responses, exception responses, trace headers, request context, access logs, request signatures, encryption, and process-local or shared JDBC replay protection.

Security

Security Foundation
Principal context facade, resolver SPI, Web context bridge, trusted-header adapter, assertions, and propagation helpers.

Data

Data Integration
MyBatis-Plus interceptor assembly, pagination, SQL guard, tenant SQL isolation, and data-permission SQL predicates.

Feature Control

Feature Control
Parent POM, BOM, one starter, declarative feature selection, dependency-aware feature plans, and runtime feature conditions.

Audit

Audit Pipeline
Structured audit logging by default, plus formatter and recorder SPI, publisher, failure policy, and access-log adaptation.

Codegen

Explicit Source Generation
Replaceable templates, built-in CRUD source scaffolding, and safe writes. Hidden runtime CRUD controllers remain out of scope.

Boundary

Coco Encapsulates Application Owns
Starter wiring and auto-configuration composition Domain model and API semantics
Feature activation, dependency propagation, and runtime feature gating Controller shape and service orchestration
Unified response, typed exceptions, i18n, trace context, and access logs Transaction boundaries and custom persistence decisions
Request signatures, encryption, replay protection, security context lifecycle bridge, audit hooks, tenant SQL, and data-permission SQL Authentication provider, user model, organization model, role model, and generated CRUD code

CRUD belongs to code generation, not runtime entity exposure. Generated code should be readable Java source that the business project can keep, edit, delete, or replace.

Extension Boundaries

Area Delivered Boundary Application or Roadmap
Replay Process-local default, explicit shared JDBC reference store, atomic key reservation, expiry cleanup, and replaceable store SPI. Database migration and availability, cluster clock synchronization, business transactions, and exactly-once semantics.
Security Context facade, resolver SPI, Servlet context bridge, trusted-header adapter, assertions, and propagation primitives. Authentication provider, RBAC/ABAC model, sessions, tokens, and user storage.
Audit Event contract, publisher, default best-effort structured logging, formatter and recorder SPI, failure policy, and access-log adapter. Database persistence, MQ delivery, compliance reports, and retention policy.
OpenAPI Metadata provider, configuration boundary, and optional SpringDoc metadata customizer when SpringDoc is already on the application classpath. Document renderer, UI integration, and endpoint-specific documentation strategy.
Codegen Generator SPI, built-in CRUD templates, an explicit Maven goal, overwrite protection, and custom template locations. Project-specific templates, business rules, and ongoing ownership of generated CRUD source.

Samples

Sample What It Proves Entry
Basic Web responses, exceptions, i18n, trace, signatures, encryption, and replay protection without a database. Open sample
Full H2 + MyBatis-Plus with security assertions, tenant SQL isolation, data-permission SQL filtering, and audit publication. Open sample

Runtime Shape

flowchart LR
    app["Business Application"] --> parent["coco-parent"]
    app --> starter["coco-spring-boot-starter"]
    starter --> config["coco-config"]
    config --> runtime["coco-feature-runtime"]
    runtime --> web["Web Runtime"]
    runtime --> security["Security Foundation"]
    runtime --> data["Data Integration"]
    web --> business["Normal Spring Business Code"]
    security --> business
    data --> business
Loading

Coco Ecosystem

Project Responsibility Repository
Coco Framework Independent Spring Boot Web server infrastructure and stable extension boundaries. coco-framework
Coco Admin ERP product and business modules built with normal application code on top of the framework. coco-admin
Coco Generate Development-time source generation, reusable template packs, and safe generated-file ownership. coco-generate

The dependency direction is intentionally one-way: Admin depends on Framework at runtime and may use Generate during development; Generate may target Framework contracts; Framework never depends on either product repository. Generated source belongs to the consuming application and does not add a runtime dependency on Generate.

Community

Contributing
Development workflow and review expectations
Discussions
Questions, ideas, and implementation guidance
Security
Supported versions and private reporting
Governance
Ownership, decisions, and protected merge controls

Star History

1
Stars
0
Forks
1
Contributors
Updated: 2026-07-13
Star History Chart

Contributors

patton174
patton174

View all contributors

The stars and contributors sections are refreshed by the README maintenance workflow. See .github/workflows/readme-maintenance.yml and .github/readme/scripts/update-insights.mjs.

License

Apache License 2.0.

About

High-convention Spring Boot framework for rapidly building production-ready web services with one starter and replaceable infrastructure.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages