The Chenile story
The website and the YouTube series share one narrative arc. Read it end to end, or jump to any chapter.
Why microservices — and what they really cost
What we actually want from microservices, and the recurring tax every team pays when the same plumbing is rebuilt service by service.
Read part 1 →Separate the service definition from the implementation
A service is a contract, not a codebase. Chenile splits the interface and model into an api module that consumers depend on, and the logic into a service module that nobody depends on.
Read part 2 →Service policies: the other half of the division
Horizontal requirements — security, logging, tenancy, i18n, retries — are not business logic. Chenile names each one a policy and implements it as a single-responsibility interceptor.
Read part 3 →Where policies live: the API gateway and the last mile
Some policies belong at the edge; others must run beside the service. Most real systems need both — and choosing well is an architectural decision, not a framework limitation.
Read part 4 →How Chenile implements policies at the gateway and the last mile
One interceptor abstraction, two deployment sites. Write a policy once; the service registry decides whether it runs at the edge, at the last mile, or both.
Read part 5 →Test once, run everywhere: BDD across unit and integration
Chenile ships a Gherkin vocabulary implemented twice — over Spring MockMvc for in-process unit tests and over REST Assured for integration tests. The same .feature file drives both.
Read part 6 →Messaging: one interface, many transports
chenile-messaging applies the same discipline to events. Services depend on a small messaging interface; MQTT, Kafka, Azure and in-JVM are swappable implementations behind it — and every message runs the same pipeline as an HTTP call.
Read part 7 →Configuration management with cconfig
cconfig gives every module its own JSON configuration, lets any value — or a nested path inside it — be overridden at runtime, and resolves the effective config per tenant. Sources are pluggable behind one client.
Read part 8 →Service registry & proxies: calling services through their interface
Chenile ships its own service registry and a proxy framework. Call another service through its Java interface — Chenile routes the call locally or remotely and runs a client-side interceptor chain on the way out.
Read part 9 →Owiz: the orchestration engine that powers Chenile
Under Chenile's interception pipeline sits Owiz — a tiny, framework-agnostic Orchestration Wizard. Commands enrich a shared context; chains, routers, splitter-aggregators and parallel blocks compose them into flows.
Read part 10 →Chenile Query: metadata-driven search over MyBatis
Describe a query's columns in JSON, pair it with a MyBatis mapper, and Chenile gives you a filter/sort/paginate/download REST endpoint — with no Java code — from the chenile-query-workflow-blueprints repo.
Read part 11 →jgen: blueprint code generation, in depth
jgen (in chenile-gen) scaffolds whole Chenile projects from blueprints — service, workflow, MyBatis query, interceptor, monolith and more. Choose a blueprint, answer a few questions, and get a project that compiles against the standard runtime.
Read part 12 →Multi-tenant SaaS, the Chenile way
One deployment, many customers. Chenile resolves the tenant once into a request context, then routes writes, reads and configuration per tenant — via multi-datasource-utils, Chenile Query and cconfig — so your business code stays tenant-agnostic.
Read part 13 →Trajectories: run alternate behaviour without branching your code
A trajectory is an ephemeral, per-request variant of the system. Set a header, and Chenile swaps in a different service implementation, a different workflow action, and different configuration — with no if-statements and nothing to untangle later.
Read part 14 →Blueprints: author your own generator
A jgen blueprint is a small plugin — a JSON contract, an optional Java hook, and a template tree. Learn its anatomy and scaffold a brand-new blueprint with the jgen-blueprint blueprint (yes, really).
Read part 15 →Polymorphism by configuration: the right code for each request
In Chenile, which code runs is decided per request from data — a header, a tenant, a payload, a workflow state — not hard-wired. Service selectors, trajectories, interceptor interpolations, body-type selectors, workflow resolvers and MCP polymorphs are one idea seen from six sides. Here is how they fit, which to reach for, and how to keep late binding from failing late.
Read part 16 →