A high-convention Spring Boot Web server framework for fast, production-ready Java services.
Install · Capabilities · SQL Guard · Boundary · Extension Boundaries · Samples · Stars · Contributors
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.
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-permissionOr 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);
}
}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:generateThe 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.
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: trueWhen enabled, MyBatis-Plus may reject legitimate SQL that should be rewritten, reviewed, or explicitly ignored only for controlled maintenance statements:
UPDATEorDELETEwithout a selectiveWHERE, or with tautological conditions such as1 = 1.SELECT,UPDATE, orDELETEwithoutWHEREwhenIllegalSQLInnerInterceptoris 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.
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_keyCoco 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.
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.
|
Web Runtime Unified responses, exception responses, trace headers, request context, access logs, request signatures, encryption, and process-local or shared JDBC replay protection. |
Security Foundation Principal context facade, resolver SPI, Web context bridge, trusted-header adapter, assertions, and propagation helpers. |
Data Integration MyBatis-Plus interceptor assembly, pagination, SQL guard, tenant SQL isolation, and data-permission SQL predicates. |
|
Feature Control Parent POM, BOM, one starter, declarative feature selection, dependency-aware feature plans, and runtime feature conditions. |
Audit Pipeline Structured audit logging by default, plus formatter and recorder SPI, publisher, failure policy, and access-log adaptation. |
Explicit Source Generation Replaceable templates, built-in CRUD source scaffolding, and safe writes. Hidden runtime CRUD controllers remain out of scope. |
| 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.
| 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. |
| 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 |
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
| 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.
| 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 |
| 1 Stars |
0 Forks |
1 Contributors |
Updated: 2026-07-13 |
|
patton174 |
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.
Apache License 2.0.